Котлин закрывает ZipInputStream до прочтения всех записей - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь прочитать сжатый файл, используя Kotlin и ZipInputStream, в ByteArrayOutputStream ()

val f = File("/path/to/zip/myFile.zip")
val zis = ZipInputStream(FileInputStream(f))

//loop through all entries in the zipped file
var entry = zis.nextEntry
while(entry != null) {
    val baos = ByteArrayOutputStream()

    //read the entry into a ByteArrayOutputStream
    zis.use{ it.copyTo(baos) }

    val bytes = baos.toByteArray()

    System.out.println(bytes[0])

    zis.closeEntry()  //error thrown here on first iteration
    entry = zis.nextEntry
}

Я получаю сообщение об ошибке:

java.io.IOException: Stream closed
    at java.util.zip.ZipInputStream.ensureOpen(ZipInputStream.java:67)
    at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:139)
    <the code above>

Я подумал, может быть zis.useзакрывает запись уже после того, как содержимое записи прочитано, поэтому я удалил zis.closeEntry(), но затем он выдал ту же ошибку при попытке получить следующую запись

Я знаю, что zis.use безопасно и гарантируетвходной поток закрыт, но я ожидаю, что он закроет только запись, а не весь поток.

Распечатав весь байтовый массив, я знаю, что только первый файл в zip-файле читается во время чтения.zis.use

Есть ли хороший способ прочитать все записи в ZipInputStream в kotlin?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

В Kotlin use закроет ресурс, который реализует AutoCloseable.Это означает, что его close() метод вызывается для вас автоматически.Я думаю, вы предполагаете, что в ZipInputStream это было переопределено для закрытия только записей, но это не так.

Согласно документации :

Закрывает этот входной поток и освобождает любые системные ресурсы, связанные с потоком .[Акцент мой]

0 голосов
/ 12 сентября 2018

Функция use вызывает метод close () , который закрывает весь поток, а не closeEntry () , который закрывает только текущую запись.Я думаю, вы должны заключить весь цикл while в zis.use { ... }, а не вызывать его для каждой записи.

...