2012-10-15 2 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); 
    } 
} 
관련 문제