How to zip the files include sub folders in android - android

I want to zip more then one directory. That mean I have 1 inner directory and 1 parent directory. Now I want to zip the parent directory.
I am using following codes:
My file Path :
/data/data/com/app/1430159400000/32640/Images/capture_Image_20150427_115541.png"
/data/data/com/app/1430159400000/32640/Images/capture_Image_20150427_115542.png"
/data/data/com/app/1430159400000/32640/Images/ChildImages/capture_Image_20150427_115543.png"
/data/data/com/app/1430159400000/32640/Images/ChildImages/capture_Image_20150427_115544.png"
/data/data/com/app/1430159400000/32640/Images/capture_Image_20150427_115545.png"
/data/data/com/app/1430159400000/32640/Images/capture_Image_20150427_115546.png"
To get the files from directory:-
public void getListFilesForCreatingZip(File parentDir) {
String[] filesPath = null;
File[] files = parentDir.listFiles();
filesPath = new String[(int) parentDir.length()];
int index = 0;
int index1=0;
for (File file : files) {
if (file.isDirectory()) {
if(file.getName().equals("ChildImages"))
{
File[] files1 = file.listFiles();
for(File ss:files1)
{
filesPath[index]=ss.getPath();
index++;
}
}
} else {
filesPath[index] = file.getPath();
}
index++;
}
zip(filesPath, "PathName";
}
To Zip files:-
public void zip(String[] _files, String zipFileName) {
try {
BufferedInputStream origin = null;
/*File root = Application.getInstance().getDir("bol", Context.MODE_PRIVATE);
File customDir = new File(root + File.separator + File.separator + PreferenceManagerForBol.getInstance().getBolSelectedDate() + File.separator + PreferenceManagerForBol.getInstance().getBolOrderNumber());
if (customDir.exists() == false) {
customDir.mkdirs();
} */
File file = new File(BolDetailsHandler.getInstance().createBasePath(), zipFileName + ".zip");
FileOutputStream dest = new FileOutputStream(file);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.length; i++) {
if(!_files[i].contains(".zip"))
{
Logger.v("Compress", "Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
When I use this following codes I am facing null pointer exception in zip() method. When zip() method try to read the child path and again try to read parent path it showing null pointer exception.
Please let me any idea to solve this.

index++;. You have two of them. Place the second one like the first one directly after filesPath[index] = file.getPath();.
But your String array filesPath = new String[(int) parentDir.length()]; will not have the right size in this way. There is no room for the files of the sub directory.
You could much better use a <String> ArrayList as then you can add as much as you want without having to know at forehand how much there will be.

Related

While zip multiple images the images size and quality gets reduced , how to solve that?

I have used below function to zip multiple images from my folder, mainViewModel.getImagesList() will return array of images path which i want to added in zip folder
public void compressImagesToZip() throws IOException {
BufferedInputStream origin = null;
String opd = Environment.getExternalStorageDirectory() + "/" + getApplication().getApplicationContext().getResources().getString(R.string.imageFolder) + "/GroTrack.zip";
Log.e("====>>", opd);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(opd)));
try {
byte data[] = new byte[2048];
for (int i = 0; i < mainViewModel.getImagesList().size(); i++) {
FileInputStream fi = new FileInputStream(mainViewModel.getImagesList().get(i));
origin = new BufferedInputStream(fi, 2048);
try {
ZipEntry entry = new ZipEntry(mainViewModel.getImagesList().get(i).substring(mainViewModel.getImagesList().get(i).lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, 2048)) != -1) {
out.write(data, 0, count);
}
} finally {
origin.close();
}
}
} finally {
out.close();
}
}
Please refere this images, before zip and after zip image sizes were different
before
after

Android Zipping files

I have a created a directory with some images stored in it. Now, to zip it as a single .zip file, I used the following code :
private static void zipDir(String zipFileName, String dir) throws Exception {
File dirObj = new File(dir);
ZipOutputStream out = new ZipOutputStream(newFileOutputStream(zipFileName));
addDir(dirObj, out);
out.close();
}
static void addDir(File dirObj, ZipOutputStream out) throws IOException {
File[] files = dirObj.listFiles();
byte[] tmpBuf = new byte[1024];
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
addDir(files[i], out);
continue;
}
FileInputStream in = new FileInputStream(files[i].getAbsolutePath());
System.out.println(" Adding: " + files[i].getAbsolutePath());
out.putNextEntry(new ZipEntry(files[i].getAbsolutePath()));
int len;
while ((len = in.read(tmpBuf)) > 0) {
out.write(tmpBuf, 0, len);
}
out.closeEntry();
in.close();
}
}
I obtained this code from the following source : http://www.java2s.com/Code/Java/File-Input-Output/Makingazipfileofdirectoryincludingitssubdirectoriesrecursively.htm
When I run this code, in the specified directory, a .zip file is created with the specified name but when I try to open it using any software(winzip, etc) on Android or on PC, it displays the error message that : This file is corrupt or not a valid zip file"
Any help would be appreciated.
I was thinking about deleting the question. But it stands for a rather interesting read. While creating the .zip file, I had specified the same directory as the one which I wanted to compress. This results in an infinite loop. Changing the .zip directory solves the issue.
I mean like this:
private static void zipDir(String zipFileName, String dir) throws Exception {
List<String> files = buildFileList(dir, "");
ZipOutputStream out = new ZipOutputStream(newFileOutputStream(zipFileName));
zipFiles(files, out);
out.close();
}
static List<String> buildFileList(String path, String filter) {
List<String> lstFile = new ArrayList<String>();
File[] files = new File(path).listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
File f = files[i];
if (f.isFile()) {
if (filter.length() == 0 || f.getName().matches(filter))
lstFile.add(f.getAbsolutePath());
} else if (f.isDirectory() && f.getPath().indexOf("/.") == -1)
lstFile.addAll(getFilePaths(f.getAbsolutePath(), filter));
}
}
return lstFile;
}
static void zipFiles(List<String> files, ZipOutputStream out) throws IOException {
byte[] tmpBuf = new byte[1024];
for (String file : files) {
if (new File(file).isDirectory()) {
continue;
}
FileInputStream in = new FileInputStream(file);
System.out.println(" Adding: " + file);
out.putNextEntry(new ZipEntry(file));
int len;
while ((len = in.read(tmpBuf)) > 0) {
out.write(tmpBuf, 0, len);
}
out.closeEntry();
in.close();
}
}

Android ZIP folders

I use this code to ZIP folders including inner folders :
public boolean zipFileAtPath(String sourcePath, String toLocation) {
// ArrayList<String> contentList = new ArrayList<String>();
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));
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;
}
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);
Log.i("ZIP SUBFOLDER", "Relative Path : " + relativePath);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
}
public String getLastPathComponent(String filePath) {
String[] segments = filePath.split("/");
String lastPathComponent = segments[segments.length - 1];
return lastPathComponent;
}
It works fine when folder looks like :
Folder
txt file
jpg file
txt file
It also works fine when folder looks like :
Folder
txt file
Folder
txt file
txt file
However in this case :
Folder
txt file
Folder
txt file
jpg file
txt file
it starts endless loop, when ZIP file continuously increases.
I noted, that it happens because this loop :
private void zipSubFolder(ZipOutputStream out, File folder,
int basePathLength) throws IOException {
.....
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
....
}
doesn't stop in the case, described above.
Any ideas why this can happen ? Thanks )
Here is the solution.
I save ZIP file inside the same folder, that is zipped. So it starts to zip the ZIP file itself, saving new ZIP file inside again and again and again.
Not sure, if it's clear, but anyway, pay attention where do you save ZIP file.

Ways to compress resources and/or files in Asset folders?

I am approaching finishing my application. My asset folder has over 20 PDF files in it, and obviously they are taking up quite a bit of space. Is there a way I can compress these files to make the Application smaller? What are other good techniques for checking / lowering memory consumption in my code / throughout my project? Thanks in advance for any input.
You could zip your files then decrompress when needed
Here's a tutorial Zip programmatically with Android
Check the java.util.zip class , it provides both zip & gzip functionality for compression and decompression.
You could also download the pdfs from another site once the application is installed
Or This Should work:
/*
*
* 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) {
// ArrayList<String> contentList = new ArrayList<String>();
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));
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);
Log.i("ZIP SUBFOLDER", "Relative Path : " + relativePath);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
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("/");
String lastPathComponent = segments[segments.length - 1];
return lastPathComponent;
}

How to zip and unzip the file with containing same directory structure

I have done some sort of Implementation, when I'm creating zip file everything is fine,zip file is created and it also contains all files without creating directory structure. It means when I unzip the file I have seen all the files without directory structure. Please help
me to sort it out..
Here is the code I have wrriten..
public void createZipFolder(String path)
{
File dir = new File(path);
String list[] = dir.list();
String name = path.substring(path.lastIndexOf("/"), path.length());
String n = path.substring(path.indexOf("/"), path.lastIndexOf("/"));
Log.d("JWP", "New Path :"+n);
String newPath;
if(!dir.canRead() || !dir.canWrite()){
return;
}
int len = list.length;
if(path.charAt(path.length() - 1) != '/'){
newPath = n + "/";
}
else{
newPath = n;
}
try{
ZipOutputStream zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(newPath + name + ".zip"),BUFFER));
for(int i = 0; i < len; i++){
zip_Folder(new File(path +"/"+ list[i]),zipOut);
}
zipOut.close();
}
catch(FileNotFoundException e){
Log.e("File Not Found", e.getMessage());
}
catch(IOException e){
Log.e("IOException", e.getMessage());
}
}
private void zip_Folder(File file, ZipOutputStream zipOut)throws IOException {
// TODO Auto-generated method stub
String s1 = file.getPath();
Log.d("JWP", "PATH "+s1);
byte data[] = new byte[BUFFER];
int read;
if(file.isFile()){
ZipEntry entry = new ZipEntry(file.getName());
zipOut.putNextEntry(entry);
BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
while((read = inputStream.read(data,0,BUFFER)) != -1){
zipOut.write(data, 0, read);
}
zipOut.closeEntry();
inputStream.close();
}
else if(file.isDirectory()){
String[] list = file.list();
int len = list.length;
for(int i = 0; i < len; i++)
zip_Folder(new File(file.getPath()+"/"+ list[i]), zipOut);
}
}
Here Is the code for Unzip...
public void extractZipFiles(String zipFile, String dir){
Log.d("JWP", "ZIP FILE :"+zipFile+ " DIR :"+dir);
byte data[] = new byte[BUFFER];
String name,path,zipDir;
ZipEntry entry;
ZipInputStream zipInputStream;
if(!(dir.charAt(dir.length() - 1) == '/' )){
dir += "/";
}
if(zipFile.contains("/")){
path = zipFile;
name = path.substring(path.lastIndexOf("/") + 1, path.length() - 4);
zipDir = dir + name + "/";
}
else{
path = dir + zipFile;
name = path.substring(path.lastIndexOf("/") + 1, path.length() - 4);
zipDir = dir + name + "/";
}
new File(zipDir).mkdir();
try{
zipInputStream = new ZipInputStream(new FileInputStream(path));
while((entry = zipInputStream.getNextEntry()) != null){
String buildDir = zipDir;
String dirs[] = entry.getName().split("/");
if(dirs != null && dirs.length > 0){
for(int i = 0; i < dirs.length - 1; i++){
buildDir += dirs[i] + "/";
new File(buildDir).mkdir();
}
}
int read = 0;
FileOutputStream out = new FileOutputStream(zipDir + entry.getName());
while((read = zipInputStream.read(data, 0, BUFFER)) != -1){
out.write(data, 0, read);
}
zipInputStream.closeEntry();
out.close();
}
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
You should add folder entries to zip as well.
I.e. create ZipEntry with directory name (and do not forget the trailing slash - it is significant for ZIP archives).
And, add file entries with the full relative path from the directory you are archiving.

Categories

Resources