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();
.tar
archivos comprimidos .tar
no están comprimidos. Tienes que ejecutar un archivo de compresión en él como gzip y convertirlo en algo como .tar.gz
.
Si solo desea archivar un directorio, eche un vistazo a: