Java: ZipFile с использованием Path

У меня есть Path сжать файл в виртуальной файловой системе (jimfs), и мне нужно открыть этот файл, используя ZipFile,

Но в конструкторе нет ZipFile получить Path только в качестве аргумента File,

Тем не менее, я не могу создать из моего Path File (path.toFile()), потому что я получаю UnsupportedOperationException, Как я могу открыть свой почтовый файл с ZipFile? Или, может быть, есть другие способы работы с zip-файлами, которых нет в файловой системе по умолчанию?

3 ответа

Решение

ZipFile Класс ограничен файлами в файловой системе.

Альтернативой было бы использовать ZipInputStream вместо. Создать InputStream от твоего Path с помощью

Path path = ...
InputStream in = Files.newInputStream(path, openOptions)

и использование InputStream создать ZipInputStream, Этот способ должен работать как положено:

ZipInputStream zin = new ZipInputStream(in)

Посмотрите на этот вопрос - есть код, который создает новую файловую систему из содержимого zip-файла:

  • Путь Зипа
  • конвертировать путь в URI
  • создать новую файловую систему для URI

Я только что решил точно такую ​​же проблему (мне нужно распаковать zip-файл, хранящийся в файловой системе JimFS)

Возникла проблема с ответом Роберта.ZipFileи подобные, но не равные. Один из больших недостатков ZipInputStream — он не дает сбоев в случае неправильного или поврежденного zip-файла. Он просто возвращает ноль сначалаnextEntryвызов. Например, следующий тест пройдет без ошибок

          @Test
    fun testZip() {
        val randomBytes = Random.nextBytes(1000)

        ZipInputStream(ByteArrayInputStream(randomBytes)).use { zis ->
            var zipEntry = zis.nextEntry
            while (zipEntry != null) {
                println(zipEntry.name)
                zipEntry = zis.nextEntry
            }
        }
    }

Таким образом, если в случае zip-файлов, полученных от пользователя или из-за нестабильной сети, нет никакой возможности проверить zip с помощьюZipInputStream. Единственный вариант здесь - использовать JavaFileSystems. Следующий тест завершится ошибкойzip END header not found. Конечно, с правильным zip-файлом newFileSystem работает нормально.

          @Test
    fun testZipFS() {
        val randomBytes = Random.nextBytes(1000)

        val tmpFile = Files.createTempFile(Path.of("/tmp"), "tmp", ".zip")
        Files.write(tmpFile, randomBytes)

        val zipFs = FileSystems.newFileSystem(srcZip, null)

        val zipRoot = zipFs.rootDirectories.single()
        Files.walk(zipRoot).forEach { p ->
            println(p.absolutePathString())
        }
    }

Другие вопросы по тегам