java compression zip tar

Hacer archivo tar por Java



compression zip (4)

He producido el siguiente código para resolver este problema. Este código verifica si alguno de los archivos que se incorporarán ya existe en el archivo tar y actualiza esa entrada. Más tarde, si no existe, agregue al final del archivo.

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 usas Gradle usa la siguiente dependencia:

compile group: ''org.apache.commons'', name: ''commons-compress'', version: ''1.+''

También probé org.xeustechnologies: jtar: 1.1, pero el rendimiento es muy inferior al proporcionado por org.apache.commons: commons-compress: 1.12

Notas sobre el rendimiento utilizando diferentes implementaciones:

Cremallera 10 veces usando Java 1.8 zip:
- java.util.zip.ZipEntry;
- java.util.zip.ZipInputStream;
- java.util.zip.ZipOutputStream;

[2016-07-19 19:13:11] Antes
[2016-07-19 19:13:18] Después
7 segundos

Taringear 10 veces usando jtar:
- org.xeustechnologies.jtar.TarEntry;
- org.xeustechnologies.jtar.TarInputStream;
- org.xeustechnologies.jtar.TarOutputStream;

[2016-07-19 19:21:23] Antes
[2016-07-19 19:25:18] Después
3m55sec

llamada de shell a Cygwin / usr / bin / tar - 10 veces
[2016-07-19 19:33:04] Antes
[2016-07-19 19:33:14] Después
14 segundos

Taringing 100 (cien) veces usando 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] Antes
[2016-07-19 23:04:48] Después
3 segundos

Taring 1000 (miles) veces usando org.apache.commons.compress:
[2016-07-19 23:10:28] Antes
[2016-07-19 23:10:48] Después
20 segundos

Quiero usar Java para comprimir una carpeta en un archivo tar (de manera programática). Creo que debe haber un código abierto o una biblioteca para hacerlo. Sin embargo, no puedo encontrar tal método.

Alternativamente, ¿podría hacer un archivo zip y renombrar su nombre extendido como .tar?

¿Alguien podría sugerir una biblioteca para hacerlo? ¡Gracias!


Miraría a Apache Commons Compress .

Hay un ejemplo en la parte inferior de esta página de ejemplos , que muestra un ejemplo de alquitrán.

TarArchiveEntry entry = new TarArchiveEntry(name); entry.setSize(size); tarOutput.putArchiveEntry(entry); tarOutput.write(contentOfEntry); tarOutput.closeArchiveEntry();


Puedes usar la biblioteca jtar - Java Tar .

Tomado de su sitio:

JTar es una biblioteca Java Tar simple, que proporciona una manera fácil de crear y leer archivos tar utilizando flujos de IO. La API es muy simple de usar y similar al paquete java.util.zip.

Un ejemplo, también de su sitio:

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