我有超过100.000个文件,差不多有4GB。 它的html因此可以压缩70-80%。 文件范围从200 KB到几乎10 MB。
我正在开发一个将文件从xml转换为html的应用程序。 最后,应用程序将html目录存档为zip文件。
我使用了一个名为“copy-maven-plugin”的maven插件。这个插件的文档非常好,很容易使用。插件使用的存档功能默认为“ant zip”,但您可以将其更改为使用TrueZip。打开它的对面。无论如何,我试图两种方式包装mye怪物文件夹。默认的Ant zip使用43分钟,TrueZip使用38分钟。在我看来,这两种方式都很重要。
然后我在命令行中尝试使用“zip -r archive folder”,只用了4分钟。 编辑:最近未能在40分钟内获得拉链。我想也许4分钟可能会以一个腐败的拉链结束。
所以我认为在处理这么多文件时,java可能不是那么好。
有没有人知道或有过这类问题的经验?
我在考虑实现自己的东西,通过改变字节读取大小,它会有所帮助吗? 我知道你可以通过ZipInj使用ZipInputStream / ZipOutputStream来限制读取的数据块来创建/解压缩zip文件并使用你自己的缓冲区大小,但我还没有尝试过。当它像永远一样,我不能一直等待发现; - )
截至昨晚,maven在一个zipIt.sh(zip -r ...)上调用exec在合理的时间内完成工作,但我想给java带来疑问。
更新1 我测试了不同的方法(所有默认压缩级别):
tar + bz2和tar + gz似乎都是很好的选择,并且给我选择压缩或速度是最重要的。
我没有测试jdk7.0 ZipOutputStream,但似乎我可能已经解决了它。我使用64KB(64 * 1024)的读缓冲区,它看起来像一个魅力。似乎我毕竟用java打了金: - )
这是我的实施
public static void main(String [] args) {
String outputFile = Config.getProperty(Property.ZIP_FILE);
String folderToAdd = Config.getProperty(Property.HTML_FOLDER);
Zipper.zip(outputFile, folderToAdd, 64*1024);
}
private static void zip(String zipFile, String sourceDirectory, int readChunk) {
ZipOutputStream out = null;
try {
//create byte buffer
byte[] buffer = new byte[readChunk];
File dirObj = new File(sourceDirectory);
out = new ZipOutputStream(new FileOutputStream(zipFile));
logger.info("Creating zip {} with read buffer '{}'", zipFile, readChunk);
addDir(dirObj, out, buffer);
} catch (IOException ioe) {
logger.error("IOException :" + ioe);
} finally {
IOUtils.closeQuietly(out);
}
}
private static void addDir(File dirObj, ZipOutputStream out, byte [] readChunk) throws IOException {
logger.debug("Zipping folder '{}'", dirObj.getName());
StopWatch watch = new StopWatch();
watch.start();
File[] files = dirObj.listFiles();
for (File file : files != null ? files : new File[0]) {
if (file.isDirectory()) {
addDir(file, out, readChunk);
continue;
}
FileInputStream in = null;
try {
in = new FileInputStream(file.getAbsolutePath());
out.putNextEntry(new ZipEntry(file.getAbsolutePath()));
int len;
while ((len = in.read(readChunk)) > 0) {
out.write(readChunk, 0, len);
}
} finally {
out.closeEntry();
IOUtils.closeQuietly(in);
}
}
watch.stop();
logger.debug("Zipped folder {} in {} seconds.", dirObj.getName(), watch);
}
答案 0 :(得分:1)
我怀疑问题是这样的文件数量。您需要能够操作ZIP条目而无需解压缩并重新打包所有条目。这可以产生显着的差异。我预计会有10倍的差异。这可以用Java完成,但我怀疑大多数库不是为此而设计的。
如果看起来像你想做的那样,你可以从Java调用zip
。许多使用命令行工具的maven插件(特别是用于版本控制的插件)
BTW你可以使用tar + bz2这样的东西获得更好的压缩效果。这通过压缩整个存档而不是单独压缩每个文件来压缩更多。这意味着如果不解压缩/重新压缩整个事物,你就无法触摸它。 (与你可能会这样做的JAR / ZIP不同)