para - como usar rar en android pdf
comprimir/comprimir una carpeta llena de archivos en Android (6)
Necesito comprimir una carpeta de "proyecto" para permitir a los usuarios compartir proyectos por correo electrónico. Encontré una clase para comprimir varios archivos en un solo archivo zip, pero necesito mantener la estructura de carpetas en mi archivo zip. ¿Hay alguna manera de lograr esto en Android? Gracias por adelantado.
Así es como lo hago:
private static void zipFolder(String inputFolderPath, String outZipPath) {
try {
FileOutputStream fos = new FileOutputStream(outZipPath);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(inputFolderPath);
File[] files = srcFile.listFiles();
Log.d("", "Zip directory: " + srcFile.getName());
for (int i = 0; i < files.length; i++) {
Log.d("", "Adding file: " + files[i].getName());
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(files[i]);
zos.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
zos.close();
} catch (IOException ioe) {
Log.e("", ioe.getMessage());
}
}
Este código debería hacer el truco.
Nota: debe agregar permisos de escritura de archivos a su aplicación agregando el permiso WRITE_EXTERNAL_STORAGE a su archivo manifest.xml.
/*
*
* Zips a file at a location and places the resulting zip file at the toLocation
* Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip");
*/
public boolean zipFileAtPath(String sourcePath, String toLocation) {
final int BUFFER = 2048;
File sourceFile = new File(sourcePath);
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(toLocation);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
if (sourceFile.isDirectory()) {
zipSubFolder(out, sourceFile, sourceFile.getParent().length());
} else {
byte data[] = new byte[BUFFER];
FileInputStream fi = new FileInputStream(sourcePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath));
entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
}
out.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/*
*
* Zips a subfolder
*
*/
private void zipSubFolder(ZipOutputStream out, File folder,
int basePathLength) throws IOException {
final int BUFFER = 2048;
File[] fileList = folder.listFiles();
BufferedInputStream origin = null;
for (File file : fileList) {
if (file.isDirectory()) {
zipSubFolder(out, file, basePathLength);
} else {
byte data[] = new byte[BUFFER];
String unmodifiedFilePath = file.getPath();
String relativePath = unmodifiedFilePath
.substring(basePathLength);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(file.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
}
/*
* gets the last path component
*
* Example: getLastPathComponent("downloads/example/fileToZip");
* Result: "fileToZip"
*/
public String getLastPathComponent(String filePath) {
String[] segments = filePath.split("/");
if (segments.length == 0)
return "";
String lastPathComponent = segments[segments.length - 1];
return lastPathComponent;
}
He modificado el código de HailZeon para que funcione correctamente en Windows. Las entradas Zip deben cerrarse antes de que se inicien las nuevas y una "/" inicial en los nombres de las entradas como "/file.txt" también genera problemas
/**
* Zips a Folder to "[Folder].zip"
* @param toZipFolder Folder to be zipped
* @return the resulting ZipFile
*/
public static File zipFolder(File toZipFolder) {
File ZipFile = new File(toZipFolder.getParent(), format("%s.zip", toZipFolder.getName()));
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(ZipFile));
zipSubFolder(out, toZipFolder, toZipFolder.getPath().length());
out.close();
return ZipFile;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* Main zip Function
* @param out Target ZipStream
* @param folder Folder to be zipped
* @param basePathLength Length of original Folder Path (for recursion)
*/
private static void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException {
final int BUFFER = 2048;
File[] fileList = folder.listFiles();
BufferedInputStream origin = null;
for (File file : fileList) {
if (file.isDirectory()) {
zipSubFolder(out, file, basePathLength);
} else {
byte data[] = new byte[BUFFER];
String unmodifiedFilePath = file.getPath();
String relativePath = unmodifiedFilePath.substring(basePathLength + 1);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(file.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
out.closeEntry();
}
}
}
Si usa un objeto java.util.zip, puede escribir un script que no modifique la estructura del directorio.
Utilice la biblioteca zip4j desde esta location . Importe el archivo jar a su carpeta "app/libs/"
. Y usa el siguiente código para comprimir tus directorios / archivos ...
try {
File input = new File("path/to/your/input/fileOrFolder");
String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "zippedItem.zip";
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
File output = new File(destinationPath);
ZipFile zipFile = new ZipFile(output);
// .addFolder or .addFile depending on your input
if (sourceFile.isDirectory())
zipFile.addFolder(input, parameters);
else
zipFile.addFile(input, parameters);
// Your input file/directory has been zipped at this point and you
// can access it as a normal file using the following line of code
File zippedFile = zipFile.getFile();
} catch (ZipException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
public static boolean zip(File sourceFile, File zipFile) {
List<File> fileList = getSubFiles(sourceFile, true);
ZipOutputStream zipOutputStream = null;
try {
zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFile));
int bufferSize = 1024;
byte[] buf = new byte[bufferSize];
ZipEntry zipEntry;
for(int i = 0; i < fileList.size(); i++) {
File file = fileList.get(i);
zipEntry = new ZipEntry(sourceFile.toURI().relativize(file.toURI()).getPath());
zipOutputStream.putNextEntry(zipEntry);
if (!file.isDirectory()) {
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
int readLength;
while ((readLength = inputStream.read(buf, 0, bufferSize)) != -1) {
zipOutputStream.write(buf, 0, readLength);
}
}
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
IoUtils.closeOS(zipOutputStream);
}
return true;
}
public static List<File> getSubFiles(File baseDir, boolean isContainFolder) {
List<File> fileList = new ArrayList<>();
File[] tmpList = baseDir.listFiles();
for (File file : tmpList) {
if (file.isFile()) {
fileList.add(file);
}
if (file.isDirectory()) {
if (isContainFolder) {
fileList.add(file); //key code
}
fileList.addAll(getSubFiles(file));
}
}
return fileList;
}