我目前正在提取一个war文件的内容,然后将一些新文件添加到目录结构中,然后创建一个新的war文件。
这一切都是在Java中以编程方式完成的--但我想知道,复制war文件然后添加文件是不是更有效率--这样我就不必等待war扩展,然后再进行压缩。
不过,在文档或任何在线示例中,我似乎找不到这样做的方法。
有谁能给点建议或指点吗?
更新:
其中一个答案中提到的TrueZip似乎是一个很好的java库,可以附加到压缩文件中(尽管其他答案说不可能做到这一点)。
有没有人对TrueZip有经验或反馈,或者可以推荐其他类似的库?
发布于 2013-07-06 23:05:05
在Java7中,我们得到了Zip File System,它允许在压缩包(jar、war)中添加和更改文件,而无需手动重新打包。
我们可以直接写入zip文件中的文件,如下例所示。
Map<String, String> env = new HashMap<>();
env.put("create", "true");
Path path = Paths.get("test.zip");
URI uri = URI.create("jar:" + path.toUri());
try (FileSystem fs = FileSystems.newFileSystem(uri, env))
{
Path nf = fs.getPath("new.txt");
try (Writer writer = Files.newBufferedWriter(nf, StandardCharsets.UTF_8, StandardOpenOption.CREATE)) {
writer.write("hello");
}
}
发布于 2010-02-15 18:17:42
正如其他人提到的,不可能将内容附加到现有的zip (或war)。但是,可以在不临时将提取的内容写入磁盘的情况下即时创建新的zip。很难猜测这会快多少,但这是使用标准Java所能达到的最快速度(至少据我所知)。正如卡洛斯·塔萨达所提到的,SevenZipJBindings可能会占用您一些额外的时间,但是将这种方法移植到SevenZipJBindings仍然比使用具有相同库的临时文件更快。
下面是一些代码,用于写入现有压缩包(war.zip)的内容,并将额外的文件(answer.txt)附加到新压缩包(append.zip)。它只需要Java5或更高版本,不需要额外的库。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
public class Main {
// 4MB buffer
private static final byte[] BUFFER = new byte[4096 * 1024];
/**
* copy input to output stream - available in several StreamUtils or Streams classes
*/
public static void copy(InputStream input, OutputStream output) throws IOException {
int bytesRead;
while ((bytesRead = input.read(BUFFER))!= -1) {
output.write(BUFFER, 0, bytesRead);
}
}
public static void main(String[] args) throws Exception {
// read war.zip and write to append.zip
ZipFile war = new ZipFile("war.zip");
ZipOutputStream append = new ZipOutputStream(new FileOutputStream("append.zip"));
// first, copy contents from existing war
Enumeration<? extends ZipEntry> entries = war.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
System.out.println("copy: " + e.getName());
append.putNextEntry(e);
if (!e.isDirectory()) {
copy(war.getInputStream(e), append);
}
append.closeEntry();
}
// now append some extra content
ZipEntry e = new ZipEntry("answer.txt");
System.out.println("append: " + e.getName());
append.putNextEntry(e);
append.write("42\n".getBytes());
append.closeEntry();
// close
war.close();
append.close();
}
}
发布于 2010-02-12 20:13:45
我以前也有过类似的需求--但它是为了读取和写入压缩文件(.war格式应该是类似的)。我尝试过使用现有的Java Zip流,但发现编写部分很麻烦--特别是涉及到目录的时候。
我将建议您尝试使用TrueZIP (开放源码- apache许可)库,该库将任何归档文件公开为虚拟文件系统,您可以像普通文件系统一样对其进行读写。它对我来说就像一个护身符,极大地简化了我的开发。
https://stackoverflow.com/questions/2223434
复制相似问题