apache commons压缩的tar问题

我正在努力尝试使用压缩库来tar某些文件。

我的代码如下,取自commons.compress wiki示例:

private static File createTarFile(String[] filePaths, String saveAs) throws Exception{ File tarFile = new File(saveAs); OutputStream out = new FileOutputStream(tarFile); TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", out); for(String filePath : filePaths){ File file = new File(filePath); TarArchiveEntry entry = new TarArchiveEntry(file); entry.setSize(file.length()); aos.putArchiveEntry(entry); IOUtils.copy(new FileInputStream(file), aos); aos.closeArchiveEntry(); } aos.finish(); out.close(); return tarFile; } 

在此过程中没有错误,但是当我尝试解压缩文件时,我得到以下内容:

 XXXX:XXXX /home/XXXX$ tar -xf typeCommandes.tar tar: Unexpected EOF in archive tar: Unexpected EOF in archive tar: Error is not recoverable: exiting now 

此外,存档的大小略小于原始文件,这对于tar来说是不正常的,因此DO存在问题……

 -rw-r--r-- 1 XXXX nobody 12902400 Jan 14 17:11 typeCommandes.tar -rw-r--r-- 1 XXXX nobody 12901888 Jan 14 17:16 typeCommandes.csv 

谁能告诉我我做错了什么? 谢谢

你没有关闭TarArchiveOutputStream 。 在aos.close()之后添加aos.finish()

对上面代码的小修正。 它不会关闭输入流,而Apache lib假定通过调用客户端来管理流。 请参阅下面的修复程序(将此代码放在’aos.putArchiveEntry(entry)’行后面):

 FileInputStream fis = new FileInputStream(fileForPuttingIntoTar); IOUtils.copy(fis, aos); fis.close(); aos.closeArchiveEntry(); 

另见我的答案

 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(); } }