Je veux utiliser Java pour compresser un dossier dans un fichier tar (de manière programmatique). Je pense qu'il doit y avoir une source ouverte ou une bibliothèque pour le faire. Cependant, je ne trouve pas une telle méthode.
Sinon, pourrais-je créer un fichier Zip et renommer son nom étendu en .tar?
N'importe qui pourrait suggérer une bibliothèque pour le faire? Merci!
Vous pouvez utiliser la jtar - Java Tar .
Tiré de leur site:
JTar est une simple bibliothèque Java Tar, qui fournit un moyen facile de créer et de lire des fichiers tar en utilisant IO streams. L'API est très simple à utiliser et similaire au package Java.util.Zip.
Un exemple, également sur leur site:
// Output file stream
FileOutputStream dest = new FileOutputStream( "c:/test/test.tar" );
// Create a TarOutputStream
TarOutputStream out = new TarOutputStream( new BufferedOutputStream( dest ) );
// Files to tar
File[] filesToTar=new File[2];
filesToTar[0]=new File("c:/test/myfile1.txt");
filesToTar[1]=new File("c:/test/myfile2.txt");
for(File f:filesToTar){
out.putNextEntry(new TarEntry(f, f.getName()));
BufferedInputStream Origin = new BufferedInputStream(new FileInputStream( f ));
int count;
byte data[] = new byte[2048];
while((count = Origin.read(data)) != -1) {
out.write(data, 0, count);
}
out.flush();
Origin.close();
}
out.close();
Je regarderais Apache Commons Compress .
Il y a un exemple à mi-chemin cette page d'exemples , qui montre un exemple tar.
TarArchiveEntry entry = new TarArchiveEntry(name);
entry.setSize(size);
tarOutput.putArchiveEntry(entry);
tarOutput.write(contentOfEntry);
tarOutput.closeArchiveEntry();
.tar
les fichiers d'archive ne sont pas compressés. Vous devez exécuter une compression de fichier dessus comme gzip et le transformer en quelque chose comme .tar.gz
.
Si vous voulez simplement archiver un répertoire, jetez un œil à:
J'ai produit le code suivant pour résoudre ce problème. Ce code vérifie si l'un des fichiers à incorporer existe déjà dans le fichier tar et met à jour cette entrée. Plus tard s'il n'existe pas, ajoutez à la fin de l'archive.
import org.Apache.commons.compress.archivers.ArchiveEntry;
import org.Apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.Apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.Apache.commons.compress.archivers.tar.TarArchiveOutputStream;
public class TarUpdater {
private static final int buffersize = 8048;
public static void updateFile(File tarFile, File[] flist) throws IOException {
// get a temp file
File tempFile = File.createTempFile(tarFile.getName(), null);
// delete it, otherwise you cannot rename your existing tar to it.
if (tempFile.exists()) {
tempFile.delete();
}
if (!tarFile.exists()) {
tarFile.createNewFile();
}
boolean renameOk = tarFile.renameTo(tempFile);
if (!renameOk) {
throw new RuntimeException(
"could not rename the file " + tarFile.getAbsolutePath() + " to " + tempFile.getAbsolutePath());
}
byte[] buf = new byte[buffersize];
TarArchiveInputStream tin = new TarArchiveInputStream(new FileInputStream(tempFile));
OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(tarFile.toPath()));
TarArchiveOutputStream tos = new TarArchiveOutputStream(outputStream);
tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
//read from previous version of tar file
ArchiveEntry entry = tin.getNextEntry();
while (entry != null) {//previous file have entries
String name = entry.getName();
boolean notInFiles = true;
for (File f : flist) {
if (f.getName().equals(name)) {
notInFiles = false;
break;
}
}
if (notInFiles) {
// Add TAR entry to output stream.
if (!entry.isDirectory()) {
tos.putArchiveEntry(new TarArchiveEntry(name));
// Transfer bytes from the TAR file to the output file
int len;
while ((len = tin.read(buf)) > 0) {
tos.write(buf, 0, len);
}
}
}
entry = tin.getNextEntry();
}
// Close the streams
tin.close();//finished reading existing entries
// Compress new files
for (int i = 0; i < flist.length; i++) {
if (flist[i].isDirectory()) {
continue;
}
InputStream fis = new FileInputStream(flist[i]);
TarArchiveEntry te = new TarArchiveEntry(flist[i],flist[i].getName());
//te.setSize(flist[i].length());
tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
tos.setBigNumberMode(2);
tos.putArchiveEntry(te); // Add TAR entry to output stream.
// Transfer bytes from the file to the TAR file
int count = 0;
while ((count = fis.read(buf, 0, buffersize)) != -1) {
tos.write(buf, 0, count);
}
tos.closeArchiveEntry();
fis.close();
}
// Complete the TAR file
tos.close();
tempFile.delete();
}
}
Si vous utilisez Gradle, utilisez la dépendance suivante:
compile group: 'org.Apache.commons', name: 'commons-compress', version: '1.+'
J'ai également essayé org.xeustechnologies: jtar: 1.1 mais les performances sont bien inférieures à celles fournies par org.Apache.commons: commons-compress: 1.12
Remarques sur les performances à l'aide de différentes implémentations:
Zipper 10 fois en utilisant Java 1.8 Zip:
- Java.util.Zip.ZipEntry;
- Java.util.Zip.ZipInputStream;
- Java.util.Zip.ZipOutputStream;
[2016-07-19 19:13:11] Avant
[2016-07-19 19:13:18] Après
7 secondes
Tarage 10 fois avec jtar:
- org.xeustechnologies.jtar.TarEntry;
- org.xeustechnologies.jtar.TarInputStream;
- org.xeustechnologies.jtar.TarOutputStream;
[2016-07-19 19:21:23] Avant
[2016-07-19 19:25:18] Après
3 min 55 s
Appel du shell à Cygwin/usr/bin/tar - 10 fois
[2016-07-19 19:33:04] Avant
[2016-07-19 19:33:14] Après
14 secondes
Tarage 100 (cent) fois en utilisant org.Apache.commons.compress:
- org.Apache.commons.compress.archivers.ArchiveEntry;
- org.Apache.commons.compress.archivers.tar.TarArchiveEntry;
- org.Apache.commons.compress.archivers.tar.TarArchiveInputStream;
- org.Apache.commons.compress.archivers.tar.TarArchiveOutputStream;
[2016-07-19 23:04:45] Avant
[2016-07-19 23:04:48] Après
3 secondes
Tarage 1000 (milliers) fois en utilisant org.Apache.commons.compress:
[2016-07-19 23:10:28] Avant
[2016-07-19 23:10:48] Après
20 secondes