Как заархивировать папки и подпапки с файлами в нем в Kotlin, используя ZipOutputStream? - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть список файлов, расположенных в разных каталогах, в некоторых каталогах есть подкаталоги и файлы. Я не могу успешно поместить ту же структуру каталогов в ZIP-файл. Вот мой код:

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)
                    }
                }
            }
        }
    }
}
}

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Это врезает вложенные папки в плоскую структуру каталогов. Если вы хотите сохранить вложенную структуру, используйте следующий код в 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 {
0 голосов
/ 07 сентября 2018

Я решил, вот полное решение:

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...