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