Android 如何压缩文件夹&;使用ZipoutStream在Kotlin中包含文件的子文件夹?
我的文件列表安排在不同的目录,一些目录将有子目录和文件在其中。我无法成功地将相同的目录结构放入zip文件中。这是我的密码:Android 如何压缩文件夹&;使用ZipoutStream在Kotlin中包含文件的子文件夹?,android,kotlin,Android,Kotlin,我的文件列表安排在不同的目录,一些目录将有子目录和文件在其中。我无法成功地将相同的目录结构放入zip文件中。这是我的密码: fun zipAll(directory: String, zipFile: String) { val sourceFile = File(directory) ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile))).use { zipFiles(it, sourceFile)
fun zipAll(directory: String, zipFile: String) {
val sourceFile = File(directory)
ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile))).use {
zipFiles(it, sourceFile)
}
}
private fun zipFiles(zipOut: ZipOutputStream, directory: File) {
val data = ByteArray(1024)
zipOut.use {
if (directory.isDirectory) {
//Adding directory
it.putNextEntry(ZipEntry(directory.name))
} else {
zipFiles(zipOut, directory)
}
for (f in directory.listFiles()) {
if (!f.name.contains(".zip") && f.exists()) {
//Adding file
FileInputStream(f).use { fi ->
BufferedInputStream(fi).use { origin ->
val entry = ZipEntry(f.name)
it.putNextEntry(entry)
while (true) {
val readBytes = origin.read(data)
if (readBytes == -1) {
break
}
it.write(data, 0, readBytes)
}
}
}
}
}
}
}
我解决了,这里是完整的解决方案:
fun zipAll(directory: String, zipFile: String) {
val sourceFile = File(directory)
ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile))).use {
it.use {
zipFiles(it, sourceFile, "")
}
}
}
private fun zipFiles(zipOut: ZipOutputStream, sourceFile: File, parentDirPath: String) {
val data = ByteArray(2048)
for (f in sourceFile.listFiles()) {
if (f.isDirectory) {
val entry = ZipEntry(f.name + File.separator)
entry.time = f.lastModified()
entry.isDirectory
entry.size = f.length()
Log.i("zip", "Adding Directory: " + f.name)
zipOut.putNextEntry(entry)
//Call recursively to add files within this directory
zipFiles(zipOut, f, f.name)
} else {
if (!f.name.contains(".zip")) { //If folder contains a file with extension ".zip", skip it
FileInputStream(f).use { fi ->
BufferedInputStream(fi).use { origin ->
val path = parentDirPath + File.separator + f.name
Log.i("zip", "Adding file: $path")
val entry = ZipEntry(path)
entry.time = f.lastModified()
entry.isDirectory
entry.size = f.length()
zipOut.putNextEntry(entry)
while (true) {
val readBytes = origin.read(data)
if (readBytes == -1) {
break
}
zipOut.write(data, 0, readBytes)
}
}
}
} else {
zipOut.closeEntry()
zipOut.close()
}
}
}
}
用法:
zipAll("Path of source files to Zip", "Path for Zip to Export")
这会将嵌套文件夹压缩到平面目录结构中。如果要保留嵌套结构,请在isDirectory If case中使用以下代码:
if (f.isDirectory) {
val path = if (parentDirPath == "") {
f.name
} else {
parentDirPath + File.separator + f.name
}
val entry = ZipEntry(path + File.separator)
entry.time = f.lastModified()
entry.isDirectory
entry.size = f.length()
zipOut.putNextEntry(entry)
//Call recursively to add files within this directory
zipFiles(zipOut, f, path)
} else {
这是我的完整解决方案。它不忽略zip,也尊重文件夹层次结构,如
这是一个有点老的问题,但我想我有一个更好的解决方案,给你:
val inputDirectory = File("/home/fred")
val outputZipFile = File.createTempFile("out", ".zip")
ZipOutputStream(BufferedOutputStream(FileOutputStream(outputZipFile))).use { zos ->
inputDirectory.walkTopDown().forEach { file ->
val zipFileName = file.absolutePath.removePrefix(inputDirectory.absolutePath).removePrefix("/")
val entry = ZipEntry( "$zipFileName${(if (file.isDirectory) "/" else "" )}")
zos.putNextEntry(entry)
if (file.isFile) {
file.inputStream().copyTo(zos)
}
}
}
您可以通过测试'file'变量过滤掉forEach循环中的一些文件(例如过滤掉zip文件以防止压缩)此脚本中可能存在问题,一些文件未压缩,脚本卡住。Umair Adil版本也会出现这种情况。
val inputDirectory = File("/home/fred")
val outputZipFile = File.createTempFile("out", ".zip")
ZipOutputStream(BufferedOutputStream(FileOutputStream(outputZipFile))).use { zos ->
inputDirectory.walkTopDown().forEach { file ->
val zipFileName = file.absolutePath.removePrefix(inputDirectory.absolutePath).removePrefix("/")
val entry = ZipEntry( "$zipFileName${(if (file.isDirectory) "/" else "" )}")
zos.putNextEntry(entry)
if (file.isFile) {
file.inputStream().copyTo(zos)
}
}
}