2012-04-04 5 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

Try изменения

OutputStream tarOut = new FileOutputStream(f2);

в

OutputStream tarOut = new FileOutputStream(f2, true); // Set добавить к истинному

+0

@biggusjimmusThanks –

+0

Спасибо. Я сделал вышеупомянутое изменение. Содержимое tar сохраняется, но новая запись (activeSensor.cfg) не добавляется в tar. Я что-то испортил с помощью пути или аргумента, переданного конструктору TarArchiveEntry? –

+0

Я использовал этот подход, прежде чем я пошел искать здесь. Кажется, что запись будет помещена за пределы tar-архива, поэтому я получаю сообщение об ошибке, но моего нового файла там не будет. – froggythefrog

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), поскольку он только считывает размеры файлов в байты целочисленной точности (см. преобразование в int). Однако это не проблема, так как Apache Compress не обрабатывает файлы более чем на 2 ГБ.
+0

Спасибо, это сработало. Мне пришлось слегка изменить код в том смысле, что я не смог выполнить весь код, который вы использовали, непосредственно в формате .tar.gz. Так что мне пришлось распаковать файл сначала, чтобы получить формат .tar. После ввода необходимой записи в файл tar в соответствии с предложенным способом мне пришлось снова заново заново закрепить ее. Для распаковки и повторной запечатки я использовал java.util.zip.GZIPInputStream и java.util.zip.GZIPOutputStream утилиты. –

Смежные вопросы