3

既存の tar ファイルに構成ファイルを追加する必要があります。apache.commons.compressライブラリを使用しています。次のコード スニペットは、エントリを正しく追加しますが、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(); 

}

tar を確認すると、「activeSensor.cfg」ファイルのみが見つかり、tar の初期コンテンツが欠落していることがわかりました。「モード」が正しく設定されていませんか?

4

2 に答える 2

3

問題は、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ファイル サイズを整数精度のバイト単位で読み取るだけだからです (int へのキャストを参照)。ただし、とにかく Apache Compress は 2 GB を超えるファイルを処理しないため、これは問題ではありません。
于 2012-04-04T09:16:06.470 に答える
1

変更してみる

OutputStream tarOut = new FileOutputStream(f2);

OutputStream tarOut = new FileOutputStream(f2, true);//追加をtrueに設定

于 2012-04-04T08:09:20.170 に答える