2012-04-04 283 views
3

我需要将配置文件添加到现有tar文件。我正在使用apache.commons.compress库。以下代码片段正确添加条目,但会覆盖tar文件的现有条目。向tar文件添加条目而不覆盖其现有内容

public static void injectFileToTar() throws IOException, ArchiveException { 
     String agentSourceFilePath = "C:\\Work\\tar.gz\\"; 
     String fileToBeAdded = "activeSensor.cfg"; 
     String unzippedFileName = "sample.tar"; 

    File f2 = new File(agentSourceFilePath+unzippedFileName); // Refers to the .tar file 
    File f3 = new File(agentSourceFilePath+fileToBeAdded); // The new entry to be added to the .tar file 

    // Injecting an entry in the tar 
    OutputStream tarOut = new FileOutputStream(f2); 
    TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", tarOut); 
    TarArchiveEntry entry = new TarArchiveEntry(fileToBeAdded); 
    entry.setMode(0100000); 
    entry.setSize(f3.length()); 
    aos.putArchiveEntry(entry); 
    FileInputStream fis = new FileInputStream(f3); 
    IOUtils.copy(fis, aos); 
    fis.close(); 
    aos.closeArchiveEntry(); 
    aos.finish(); 
    aos.close(); 
    tarOut.close(); 

}

在检查焦油,只有“activeSensor.cfg”的文件被发现,焦油的初始内容不翼而飞。 “模式”设置不正确?

回答

0

尝试改变

OutputStream tarOut = new FileOutputStream(f2);

OutputStream tarOut = new FileOutputStream(f2, true); //设置追加到真正

+0

@biggusjimmusThanks – 2012-04-04 08:32:21

+0

谢谢。我做了上述改变。 tar内容被保留,但新条目(activeSensor.cfg)不会被添加到焦油中。我是否将传递给TarArchiveEntry构造函数的路径或参数搞乱了? – 2012-04-04 08:44:51

+0

在我去这里搜索之前,我正在使用这种方法。似乎导致条目超出tar归档的末尾,所以我会得到一个错误,但我的新文件不会在那里。 – froggythefrog 2017-05-11 02:09:30

2

的问题是,TarArchiveOutputStream不会自动在现有的档案,这是一件好事阅读你需要这样做。

CompressorStreamFactory csf = new CompressorStreamFactory(); 
ArchiveStreamFactory asf = new ArchiveStreamFactory(); 

String tarFilename = "test.tgz"; 
String toAddFilename = "activeSensor.cfg"; 
File toAddFile = new File(toAddFilename); 
File tempFile = File.createTempFile("updateTar", "tgz"); 
File tarFile = new File(tarFilename); 

FileInputStream fis = new FileInputStream(tarFile); 
CompressorInputStream cis = csf.createCompressorInputStream(CompressorStreamFactory.GZIP, fis); 
ArchiveInputStream ais = asf.createArchiveInputStream(ArchiveStreamFactory.TAR, cis); 

FileOutputStream fos = new FileOutputStream(tempFile); 
CompressorOutputStream cos = csf.createCompressorOutputStream(CompressorStreamFactory.GZIP, fos); 
ArchiveOutputStream aos = asf.createArchiveOutputStream(ArchiveStreamFactory.TAR, cos); 

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

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

aos.finish(); 

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

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

有两点要注意:沿东西线

  • 这个代码不包括任何异常处理(请添加相应的try-catch-finally块)
  • 此代码不处理与文件超过2147483647(Integer.MAX_VALUE)的大小,因为它只将文件大小读取为整数精度字节(请参阅cast转换为int)。但是,这不是问题,因为无论如何,Apache Compress都不能处理超过2 GB的文件。
+0

谢谢,它工作。我不得不稍微调整代码,因为我无法直接以.tar.gz文件格式执行您共享的整个代码。 所以我必须首先解压文件才能达到.tar格式。按照建议的方式在tar文件中注入必需的条目后,我不得不重新压缩它。 对于解压缩和重新压缩,我使用了 java.util.zip.GZIPInputStream和java.util.zip.GZIPOutputStream实用程序。 – 2012-04-04 12:38:16