2010-01-14 102 views
1

我很难尝试使用压缩库来压缩一些文件。apache commons压缩tar问题

我的代码如下,并从commons.compress维基exemples采取:

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 

此外,存档的大小比原始文件,这心不是正常的焦油略低较小,所以有做的是问题...

-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 

任何人都可以告诉我我做错了什么?谢谢

回答

3

你没有关闭TarArchiveOutputStream。后aos.finish()

+0

是啊,这是...谢谢 – 2010-01-14 16:55:40

1

对上述代码的小修改。 它不关闭输入流,而Apache lib假定该流通过调用客户端进行管理。 请参阅下面的修复(把这段代码行之后 'aos.putArchiveEntry(进入)'):

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

参见我的答案here

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