通过Java生成tar文件

我想使用Java将文件夹压缩为tar文件(以编程方式)。 我认为必须有一个开源或库来实现它。 但是,我找不到这样的方法。

或者,我可以制作一个zip文件并将其扩展名重命名为.tar吗?

有人可以建议图书馆这样做吗? 谢谢!

您可以使用jtar – Java Tar库 。

取自他们的网站:

JTar是一个简单的Java Tar库,它提供了一种使用IO流创建和读取tar文件的简便方法。 API使用起来非常简单,与java.util.zip包类似。

一个例子,也来自他们的网站:

// Output file stream FileOutputStream dest = new FileOutputStream( "c:/test/test.tar" ); // Create a TarOutputStream TarOutputStream out = new TarOutputStream( new BufferedOutputStream( dest ) ); // Files to tar File[] filesToTar=new File[2]; filesToTar[0]=new File("c:/test/myfile1.txt"); filesToTar[1]=new File("c:/test/myfile2.txt"); for(File f:filesToTar){ out.putNextEntry(new TarEntry(f, f.getName())); BufferedInputStream origin = new BufferedInputStream(new FileInputStream( f )); int count; byte data[] = new byte[2048]; while((count = origin.read(data)) != -1) { out.write(data, 0, count); } out.flush(); origin.close(); } out.close(); 

我会看看Apache Commons Compress 。

这个示例页面有一个示例,它显示了一个tar示例。

 TarArchiveEntry entry = new TarArchiveEntry(name); entry.setSize(size); tarOutput.putArchiveEntry(entry); tarOutput.write(contentOfEntry); tarOutput.closeArchiveEntry(); 

.tar存档文件未压缩。 你必须像gzip一样对它进行文件压缩,然后把它变成类似.tar.gz东西。

如果您只想归档目录,请查看:

我已经生成了以下代码来解决这个问题。 此代码检查要合并的文件是否已存在于tar文件中并更新该条目。 如果它不存在则稍后追加到存档的末尾。

 import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; public class TarUpdater { private static final int buffersize = 8048; public static void updateFile(File tarFile, File[] flist) throws IOException { // get a temp file File tempFile = File.createTempFile(tarFile.getName(), null); // delete it, otherwise you cannot rename your existing tar to it. if (tempFile.exists()) { tempFile.delete(); } if (!tarFile.exists()) { tarFile.createNewFile(); } boolean renameOk = tarFile.renameTo(tempFile); if (!renameOk) { throw new RuntimeException( "could not rename the file " + tarFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath()); } byte[] buf = new byte[buffersize]; TarArchiveInputStream tin = new TarArchiveInputStream(new FileInputStream(tempFile)); OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(tarFile.toPath())); TarArchiveOutputStream tos = new TarArchiveOutputStream(outputStream); tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); //read from previous version of tar file ArchiveEntry entry = tin.getNextEntry(); while (entry != null) {//previous file have entries String name = entry.getName(); boolean notInFiles = true; for (File f : flist) { if (f.getName().equals(name)) { notInFiles = false; break; } } if (notInFiles) { // Add TAR entry to output stream. if (!entry.isDirectory()) { tos.putArchiveEntry(new TarArchiveEntry(name)); // Transfer bytes from the TAR file to the output file int len; while ((len = tin.read(buf)) > 0) { tos.write(buf, 0, len); } } } entry = tin.getNextEntry(); } // Close the streams tin.close();//finished reading existing entries // Compress new files for (int i = 0; i < flist.length; i++) { if (flist[i].isDirectory()) { continue; } InputStream fis = new FileInputStream(flist[i]); TarArchiveEntry te = new TarArchiveEntry(flist[i],flist[i].getName()); //te.setSize(flist[i].length()); tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU); tos.setBigNumberMode(2); tos.putArchiveEntry(te); // Add TAR entry to output stream. // Transfer bytes from the file to the TAR file int count = 0; while ((count = fis.read(buf, 0, buffersize)) != -1) { tos.write(buf, 0, count); } tos.closeArchiveEntry(); fis.close(); } // Complete the TAR file tos.close(); tempFile.delete(); } } 

如果使用Gradle,请使用以下依赖项:

 compile group: 'org.apache.commons', name: 'commons-compress', version: '1.+' 

我也试过org.xeustechnologies:jtar:1.1但是性能低于org.apache.commons提供的性能:commons-compress:1.12

使用不同实现的性能说明:

使用Java 1.8 zip压缩10次:
- java.util.zip.ZipEntry;
- java.util.zip.ZipInputStream;
- java.util.zip.ZipOutputStream;

[2016-07-19 19:13:11]之前
[2016-07-19 19:13:18]之后
7秒

使用jtar进行10次定位:
- org.xeustechnologies.jtar.TarEntry;
- org.xeustechnologies.jtar.TarInputStream;
- org.xeustechnologies.jtar.TarOutputStream;

[2016-07-19 19:21:23]之前
[2016-07-19 19:25:18]之后
3m55sec

shell调用Cygwin / usr / bin / tar - 10次
[2016-07-19 19:33:04]之前
[2016-07-19 19:33:14]之后
14秒

使用org.apache.commons.compress进行100(100)次攻击:
- org.apache.commons.compress.archivers.ArchiveEntry;
- org.apache.commons.compress.archivers.tar.TarArchiveEntry;
- org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
- org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;

[2016-07-19 23:04:45]之前
[2016-07-19 23:04:48]之后
3秒

使用org.apache.commons.compress进行1000(千)次攻击:
[2016-07-19 23:10:28]之前
[2016-07-19 23:10:48]之后
20秒

你有没有看过这个(谷歌搜索“Java tar库”):

http://www.trustice.com/java/tar/

事实上, 谷歌搜索会带来很多图书馆。