2012-10-15 61 views
4

我讀How do I append files to a tar archive in java?append files to an archive without reading/rewriting the whole archiveAdd an entry to a tar file without overwriting its existing contents但沒有給出好的答案。而且我沒有足夠的聲望發表評論。所以我在這裏創建了一個新問題。如何使用Apache Commons Compress將文件追加到.tar歸檔文件中?

有沒有辦法在tar檔案中附加文件?我想替換一個文件,如果它已經存在。

我已經開始編寫下面的方法,但是當添加文件時,它會清除存檔內容。我在apache compress website上找不到任何示例。

static final Logger LOG = Logger.getLogger(ShellClient.class); 

public void appendFileInTarArchive(String tarPath, String tarFileName, String file2WriteName, String file2WriteContent) throws IOException { 
    if (tarPath == null || tarFileName == null || tarFileName.isEmpty()) { 
     LOG.warn("The path or the name of the tar archive is null or empty."); 
     return; 
    } 
    final File tarFile = new File(tarPath, tarFileName); 
    final File fileToAdd = new File(tarPath, file2WriteName); 
    FileUtils.write(fileToAdd, file2WriteContent); 

    if (file2WriteName == null || file2WriteName.isEmpty()) { 
     LOG.warn("The name of the file to append in the archive is null or empty."); 
     return; 
    } 

    TarArchiveOutputStream aos = null; 
    OutputStream out = null; 

    try { 
     out = new FileOutputStream(tarFile); 

     aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.TAR, out); 

     // create a new entry 
     final TarArchiveEntry entry = new TarArchiveEntry(fileToAdd); 
     entry.setSize(fileToAdd.length()); 

     // add the entry to the archive 
     aos.putArchiveEntry(entry); 
     InputStream is = new FileInputStream(fileToAdd); 
     final int byteCopied = IOUtils.copy(is, aos); 
     if (LOG.isDebugEnabled()) { 
      LOG.debug(byteCopied+" bytes inserted in the tar archive from "+fileToAdd); 
     } 
     is.close(); 
     aos.closeArchiveEntry(); 
     aos.finish(); 
     aos.flush(); 
     aos.close(); 
     out.flush(); 
     out.close(); 

    } catch (ArchiveException e) { 
     LOG.error(e.getMessage(), e); 
    } catch (IOException e) { 
     LOG.error(e.getMessage(), e); 
    } finally { 
     IOUtils.closeQuietly(aos); 
     IOUtils.closeQuietly(out); 
     FileUtils.deleteQuietly(fileToAdd); 
    } 
} 

回答

4

最後我成功地用this post來做。

我創建了tar存檔的副本並將其複製到整個內容中。然後我刪除舊的tar檔案。

public void appendFileInTarArchive(String tarPath, String tarFileName, String file2WriteName, String file2WriteContent) throws AuthenticationException, IOException { 
    if (tarPath == null || tarFileName == null || tarFileName.isEmpty()) { 
     LOG.warn("The path or the name of the tar archive is null or empty."); 
     return; 
    } 
    final File tarFile = new File(tarPath, tarFileName); 
    final File fileToAdd = new File(tarPath, file2WriteName); 
    FileUtils.write(fileToAdd, file2WriteContent); 

    if (file2WriteName == null || file2WriteName.isEmpty()) { 
     LOG.warn("The name of the file to append in the archive is null or empty."); 
     return; 
    } 

    ArchiveStreamFactory asf = new ArchiveStreamFactory(); 

    File tempFile = new File(tarPath, "tmpTar.tar"); 
    tempFile.createNewFile(); 

    try { 
     FileInputStream fis = new FileInputStream(tarFile); 
     ArchiveInputStream ais = asf.createArchiveInputStream(ArchiveStreamFactory.TAR, fis); 

     FileOutputStream fos = new FileOutputStream(tempFile); 
     ArchiveOutputStream aos = asf.createArchiveOutputStream(ArchiveStreamFactory.TAR, fos); 

     // copy the existing entries  
     ArchiveEntry nextEntry; 
     while ((nextEntry = ais.getNextEntry()) != null) { 
      aos.putArchiveEntry(nextEntry); 
      IOUtils.copy(ais, aos); 
      aos.closeArchiveEntry(); 
     } 

     // create the new entry 
     TarArchiveEntry entry = new TarArchiveEntry(file2WriteName); 
     entry.setSize(fileToAdd.length()); 
     aos.putArchiveEntry(entry); 
     IOUtils.copy(new FileInputStream(fileToAdd), aos); 
     aos.closeArchiveEntry(); 

     aos.finish(); 

     ais.close(); 
     aos.close(); 

     // copies the new file over the old 
     tarFile.delete(); 
     tempFile.renameTo(tarFile); 

    } catch (ArchiveException e) { 
     LOG.error(e.getMessage(), e); 
    } catch (IOException e) { 
     LOG.error(e.getMessage(), e); 
    } finally { 
     FileUtils.deleteQuietly(fileToAdd); 
    } 
} 
相關問題