2012-04-04 3 views
3

Je dois ajouter un fichier de configuration à un fichier tar existant. J'utilise apache.commons.compress bibliothèque. L'extrait de code suivant ajoute l'entrée correctement mais écrase les entrées existantes du fichier tar.Ajouter une entrée à un fichier tar sans écraser son contenu existant

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(); 

}

Lors de la vérification du goudron, seul fichier « activeSensor.cfg » a été trouvé et le contenu initial du goudron se trouve manquante. Le "mode" n'est-il pas réglé correctement?

Répondre

0

Essayez de changer

OutputStream tarOut = new FileOutputStream(f2);

à

OutputStream tarOut = new FileOutputStream(f2, true); // Set ajouter à true

+0

@biggusjimmusMerci –

+0

Merci. J'ai fait le changement ci-dessus. Le contenu de tar est conservé mais la nouvelle entrée (activeSensor.cfg) n'est pas ajoutée au tar. Suis-je quelque chose avec le chemin ou l'argument passé au constructeur TarArchiveEntry? –

+0

J'utilisais cette approche avant d'aller chercher ici. Semble que cela provoque l'entrée à mettre au-delà de la fin de l'archive tar, donc j'obtiendrais une erreur à cet effet, mais mon nouveau fichier ne serait pas là. – froggythefrog

2

Le problème est que le TarArchiveOutputStream ne lit pas automatiquement dans l'archive existante, ce qui est quelque chose que tu devrais faire. Quelque chose le long des lignes de:

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); 

Quelques notes:

  • Ce code ne comprend pas la gestion des exceptions (s'il vous plaît ajouter les try-catch-finally appropriés blocs)
  • Ce code ne gère pas les fichiers avec une taille supérieure à 2147483647 (Integer.MAX_VALUE) car elle ne lit que les tailles de fichier à des octets de précision entiers (voir la conversion en int). Cependant, ce n'est pas un problème car Apache Compress ne gère pas les fichiers de plus de 2 Go de toute façon.
+0

Merci, cela a fonctionné. J'ai dû modifier légèrement le code dans le sens où je n'étais pas capable d'exécuter le code entier que vous partagiez, directement au format de fichier .tar.gz. J'ai donc dû d'abord décompresser le fichier pour arriver au format .tar. Après avoir injecté l'entrée requise dans le fichier tar de la manière suggérée, j'ai dû refaire le zip. Pour décompresser et re-zipper, j'ai utilisé les utilitaires java.util.zip.GZIPInputStream et java.util.zip.GZIPOutputStream. –

Questions connexes