Обновление файла в zip-архиве - PullRequest
1 голос
/ 28 февраля 2020

Я хочу обновить файл внутри zip-архива без необходимости создавать новый архив. Я знаю, что это можно сделать, создав новый архив, скопировав все остальные файлы и добавив измененный в.

Вот код, демонстрирующий проблему. Первый раздел создает исходный zip-архив, содержащий один файл с содержимым Hello world!. Второй раздел должен заменить этот контент на Bye, bye!. В последнем разделе снова распаковывается zip-архив, поэтому можно ожидать, что содержимое будет:

try {
    // Create the initial zip archive with the original file content
    File file1 = new File(ReplaceFileInZipDemo.class.getResource("/helloworld.txt").toURI());
    File zipFile = new File("output.zip");
    FileOutputStream fos = new FileOutputStream(zipFile);
    ZipOutputStream zipOut = new ZipOutputStream(fos);
    FileInputStream fis = new FileInputStream(file1);
    ZipEntry zipEntry = new ZipEntry(file1.getName());
    zipOut.putNextEntry(zipEntry);
    byte[] bytes = new byte[1024];
    int length;
    while ((length = fis.read(bytes)) >= 0) {
        zipOut.write(bytes, 0, length);
    }
    fis.close();
    zipOut.close();
    fos.close();

    // Replace the original file content with a different file content, updating the file.
    File file2 = new File(ReplaceFileInZipDemo.class.getResource("/goodbyeworld.txt").toURI());
    Path zipfile = zipFile.toPath();
    FileSystem fs = FileSystems.newFileSystem(zipfile, null);
    Path pathInZipfile = fs.getPath(file1.getName());
    Files.copy(file2.toPath() , pathInZipfile, StandardCopyOption.REPLACE_EXISTING );

    // Extract the content of the updated file
    String destinationDir = System.getProperty("java.io.tmpdir");
    File targetDir = new File(destinationDir);
    ZipInputStream i = new ZipInputStream(new FileInputStream(zipFile));
    ZipEntry entry = null;
    System.out.println("Original file content:");
    Files.readAllLines(file1.toPath(), StandardCharsets.UTF_8).forEach(line -> System.out.println(line));
    System.out.println("Expected replaced file content");
    Files.readAllLines(file2.toPath(), StandardCharsets.UTF_8).forEach(line -> System.out.println(line));
    while ((entry = i.getNextEntry()) != null) {
        File destFile = new File(targetDir, entry.getName());
        String name = destFile.getAbsolutePath();
        File f = new File(name);
        try (OutputStream o = Files.newOutputStream(f.toPath())) {
            IOUtils.copy(i, o);
        }
        System.out.println("Content of extracted file " + name);
        Files.readAllLines(f.toPath(), StandardCharsets.UTF_8).forEach(line -> System.out.println(line));

    }
} catch (Exception e) {
    e.printStackTrace();
}

Вывод, который я получаю, таков:

Original file content:
Hello world!
Expected replaced file content
Bye, bye!
Content of extracted file /tmp/helloworld.txt
Hello world!

Единственная причина, по которой я мог себе это представить не работает должным образом из-за того, что содержимое замены происходит из файла с другим именем, чем в архиве. Но при добавлении Files.delete(pathInZipfile); для полного удаления исходного файла он все еще там.

Как заменить содержимое файла в архиве содержимым другого файла?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...