Gro*_*hal 56 java zip war truezip
我目前正在提取war文件的内容,然后将一些新文件添加到目录结构,然后创建一个新的war文件.
这一切都是以编程方式从Java完成的 - 但是我想知道复制war文件然后只是附加文件会不会更有效 - 那么我就不必等待战争扩展然后必须再次压缩.
我似乎无法在文档或任何在线示例中找到这样做的方法.
任何人都可以提供一些提示或指示?
更新:
其中一个答案中提到的TrueZip似乎是一个非常好的java库附加到一个zip文件(尽管其他答案说它不可能这样做).
任何人都有关于TrueZip的经验或反馈,或者可以推荐其他类似的图书馆?
Grz*_*Żur 79
在Java 7中,我们获得了Zip文件系统,允许在zip(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");
}
}
Run Code Online (Sandbox Code Playgroud)
sfu*_*ger 44
正如其他人所提到的,不可能将内容附加到现有的zip(或战争).但是,可以动态创建新的zip,而无需将提取的内容临时写入磁盘.很难猜测它会有多快,但它是用标准Java获得的最快(至少据我所知).正如Carlos Tasada所提到的,SevenZipJBindings可能会挤出你一些额外的时间,但是将这种方法移植到SevenZipJBindings仍然比使用具有相同库的临时文件更快.
这里有一些编写现有zip(war.zip)内容的代码,并将一个额外的文件(answer.txt)附加到一个新的zip(append.zip).所需要的只是Java 5或更高版本,不需要额外的库.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
gnl*_*gic 25
我曾经有过类似的要求 - 但它是用于读取和编写zip档案(.war格式应该类似).我尝试使用现有的Java Zip流程,但发现写入部分很麻烦 - 尤其是涉及到的目录时.
我建议你试试TrueZIP(开源 - apache风格许可)库,将任何存档公开为虚拟文件系统,你可以像普通文件系统一样读写.它对我来说就像一个魅力,并大大简化了我的发展.
Lia*_*rth 14
你可以使用我写的这段代码
public static void addFilesToZip(File source, File[] files)
{
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[1024];
ZipInputStream zin = new ZipInputStream(new FileInputStream(tmpZip));
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(source));
for(int i = 0; i < files.length; i++)
{
InputStream in = new FileInputStream(files[i]);
out.putNextEntry(new ZipEntry(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())
{
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();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
75600 次 |
| 最近记录: |