我想使用Java将文件夹压缩为tar文件(以编程方式)。我认为必须有一个开源或库才能做到这一点。但是,我找不到这样的方法。
或者,我可以创建一个压缩文件并将其扩展名重命名为.tar吗?
有没有人能推荐一个图书馆来做这件事?谢谢!
发布于 2011-08-09 22:40:33
在this examples page下面有一个示例,它展示了一个tar示例。
TarArchiveEntry entry = new TarArchiveEntry(name);
entry.setSize(size);
tarOutput.putArchiveEntry(entry);
tarOutput.write(contentOfEntry);
tarOutput.closeArchiveEntry();
发布于 2016-07-21 03:28:56
我已经生成了以下代码来解决这个问题。此代码检查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.xeusttechnology:jtar:1.1,但性能远低于org.apache.commons:commons-compress:1.12
关于使用不同实现的性能的说明:
使用Java 1.8压缩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后
3m55秒
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秒
https://stackoverflow.com/questions/6997869
复制相似问题