重複の可能性:
Javaを使用してZipファイルにファイルを追加する
ZipOutputStreamでファイルを開くと、ファイルが上書きされます。ファイルを保持して新しいエントリを追加する方法はありますか?
この関数は、既存のZipファイルの名前を一時ファイルに変更してから、既存のZip内のすべてのエントリを新しいファイルとともに追加します。ただし、新しいファイルの1つと同じ名前のZipエントリは除きます。
public static void addFilesToExistingZip(File zipFile,
File[] files) throws IOException {
// get a temp file
File tempFile = File.createTempFile(zipFile.getName(), null);
// delete it, otherwise you cannot rename your existing Zip to it.
tempFile.delete();
boolean renameOk=zipFile.renameTo(tempFile);
if (!renameOk)
{
throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
}
byte[] buf = new byte[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String name = entry.getName();
boolean notInFiles = true;
for (File f : files) {
if (f.getName().equals(name)) {
notInFiles = false;
break;
}
}
if (notInFiles) {
// Add Zip entry to output stream.
out.putNextEntry(new ZipEntry(name));
// Transfer bytes from the Zip file to the output file
int len;
while ((len = zin.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
entry = zin.getNextEntry();
}
// Close the streams
zin.close();
// Compress the files
for (int i = 0; i < files.length; i++) {
InputStream in = new FileInputStream(files[i]);
// Add Zip entry to output stream.
out.putNextEntry(new ZipEntry(files[i].getName()));
// Transfer bytes from the file to the Zip file
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// Complete the entry
out.closeEntry();
in.close();
}
// Complete the Zip file
out.close();
tempFile.delete();
}
zipFile.entries()
を使用して、既存のファイル内のすべてのZipEntry
オブジェクトの列挙を取得し、それらをループしてすべてZipOutputStream
に追加してから、さらに新しいエントリ。
これは、Zipアーカイブの変更に関するJavaWorldの 詳細記事 です。
Zipに追加された非圧縮ファイルのCRC32を必ず追加する必要があります。こちらの例をご覧ください。 http://jcsnippets.atspace.com/Java/input-output/create-Zip-file.html
Zip4jを使用すると、すべてを書き直すことなく、簡単な方法でそれを行うことができます。ここに表示されます: http://blog.michalszalkowski.com/Java/Zip4j-add-file-to-existing-Zip-file/
また、SplitOutputStreamを一緒に使用して、Zip4JのZipOutputStreamを使用してそれを行うこともできます。
<dependency>
<groupId>net.lingala.Zip4j</groupId>
<artifactId>Zip4j</artifactId>
<version>1.3.1</version>
</dependency>
例:
ZipFile zipFile = new ZipFile(new File("/home/szalek/Zip/core1.Zip"));
ArrayList filesToAdd = new ArrayList();
filesToAdd.add(new File("/home/szalek/Zip/someData.txt"));
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//password
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
parameters.setPassword("test123!");
//password
zipFile.addFiles(filesToAdd, parameters);