所以我有兴趣将文件附加到zip存档,我遇到了一些之前提出过这个问题的用户,另一位用户提供了此代码片段作为该问题的解决方案:
public static void updateZip(File source, File[] files, String path){
try{
File tmpZip = File.createTempFile(source.getName(), null);
tmpZip.delete();
if(!source.renameTo(tmpZip)){
throw new Exception("Could not make temp file (" + source.getName() + ")");
}
byte[] buffer = new byte[4096];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));
for(int i = 0; i < files.length; i++){
System.out.println(files[i].getName()+"being read");
InputStream in = new FileInputStream(files[i]);
out.putNextEntry(new ZipEntry(path + files[i].getName()));
for(int read = in.read(buffer); read > -1; read = in.read(buffer)){
out.write(buffer, 0, read);
}
out.closeEntry();
in.close();
}
for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){
if(!zipEntryMatch(ze.getName(), files, path)){
out.putNextEntry(ze);
for(int read = zin.read(buffer); read > -1; read = zin.read(buffer)){
out.write(buffer, 0, read);
}
out.closeEntry();
}
}
out.close();
tmpZip.delete();
}catch(Exception e){
e.printStackTrace();
}
}
private static boolean zipEntryMatch(String zeName, File[] files, String path){
for(int i = 0; i < files.length; i++){
if((path + files[i].getName()).equals(zeName)){
return true;
}
}
return false;
}
我创建了一个迷你程序来测试这个方法,这是完成所有工作的方法:
private static void appendArchive() {
String filename = "foo";
File[] filelist = new File[10];
int i = 0;
String temp = "";
while (!filename.trim().equals("")) {
System.out
.println("Enter file names to add, then enter an empty line");
filename = getInput();
filelist[i] = new File(filename, filename);
System.out.println("Adding " + filelist[i].getName());
}
System.out
.println("What is the name of the zip archive you want to append");
File zipSource = new File(getInput() + ".zip", "testZip.zip");
try {
Archiver.updateZip(zipSource, filelist, "");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
每当我尝试运行此程序时,我都会收到此错误,然后是下一个错误:
java.lang.Exception: Could not make temp file (testZip.zip)
at Archiver.updateZip(Archiver.java:68)
at main.appendArchive(main.java:62)
at main.main(main.java:29)
我怀疑我传递的zip文件由于某种原因被认为是开放的,因此重命名方法不适用于Windows,所以我尝试使用你现在看到的zip文件的构造函数。这到底我到底做错了什么?我的测试输入对于文件是2,而2是(附加到2.zip)。它不应该是任何目录相关的问题,因为文件是由程序生成的。
答案 0 :(得分:0)
作品找到我。我怀疑你可能想检查tmpZip.delete()
的操作。
if (!tmpZip.exists() || tmpZip.delete()) {
// ... Continue
} else {
// ... File is locked
}
<强>更新强>
我一直在玩代码,还有一些额外的缺陷......
将旧条目添加到新文件时,您正在使用现有的ZipEntry
条目。如果产生的压缩不同,这将失败。您应该创建一个新的ZipEntry
添加用途,而不是
ZipEntry ne = new ZipEntry(ze.getName());
out.putNextEntry(ne);
// Write bytes to file...
out.closeEntry();
您永远不会关闭ZipInputStream
,这意味着最后tmpZip.delete()
会失败。
你的错误处理就在不存在......
ZipInputStream zin = null;
ZipOutputStream out = null;
try {
// Append zip ...
} finally {
try {
zin.close();
} catch (Exception exp) {
}
try {
out.close();
} catch (Exception exp) {
}
}
将阻止未来的文件锁定(我故意没有抓住IOException
,因为我个人认为它应该被召回到被叫方)
您不应该覆盖已完成的现有zip文件。您应该为新的zip文件创建一个临时文件,将所有文件写入其中,附加现有文件,完成后,用临时文件替换现有文件。
这意味着,如果出现问题,您就不会破坏现有的zip文件。
IMHO