I want to zip a folder. Actually I managed it.But there is a problem. if there is a empty folder in my directory, the empty folder is not created in my zip file
For example my directory is:
/folder
/folder/temp.txt
/folder/emptyfolder
when I zip this directory with my code, emptyfolder doesn't exist in my zip file. I find problem.Problem is that files.length == 0 so for loop doesn't work.But I didn't find a solution. How to create the empty folder in my zip file?
private static final void zip(File directory, File base,
ZipOutputStream zos) throws IOException {
File[] files;
if(directory.isDirectory()) // folder
{
files = directory.listFiles();
}else
{
files = new File[1]; // file
files[0] = directory;
}
byte[] buffer = new byte[8192];
int read = 0;
for (int i = 0, n = files.length; i < n; i++)
{
if (files[i].isDirectory())
{
zip(files[i], base, zos);
}
else
{
FileInputStream in = new FileInputStream(files[i]);
ZipEntry entry = new ZipEntry(files[i].getPath().substring(
base.getPath().lastIndexOf("/") + 1));
zos.putNextEntry(entry);
while (-1 != (read = in.read(buffer)))
{
zos.write(buffer, 0, read);
}
in.close();
}
}
Related
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();
}
}
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.
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.
Please, suggest me the best way of copying a folder from assets to /data/data/my_app_pkg/files.
The folder from assets (www) contains files and subfolders. which I want to completely copy to the files/ of my internal app path mentioned.
I am successfully able to copy a file from assets to internal app files/ path, but unable to do the same in case of copying folder, even assetmanager.list isn't helping me out, as it is copying only the files, but not the directories / subfolders.
Please kindly suggest me the better way to do what I want
Hope use full to you below code:-
Copy files from a folder of SD card into another folder of SD card
Assets
AssetManager am = con.getAssets("folder/file_name.xml");
public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
throws IOException {
if (sourceLocation.isDirectory()) {
if (!targetLocation.exists()) {
targetLocation.mkdir();
}
String[] children = sourceLocation.list();
for (int i = 0; i < sourceLocation.listFiles().length; i++) {
copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
new File(targetLocation, children[i]));
}
} else {
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
Hope this will help
private void getAssetAppFolder(String dir) throws Exception{
{
File f = new File(sdcardlocation + "/" + dir);
if (!f.exists() || !f.isDirectory())
f.mkdirs();
}
AssetManager am=getAssets();
String [] aplist=am.list(dir);
for(String strf:aplist){
try{
InputStream is=am.open(dir+"/"+strf);
copyToDisk(dir,strf,is);
}catch(Exception ex){
getAssetAppFolder(dir+"/"+strf);
}
}
}
public void copyToDisk(String dir,String name,InputStream is) throws IOException{
int size;
byte[] buffer = new byte[2048];
FileOutputStream fout = new FileOutputStream(sdcardlocation +"/"+dir+"/" +name);
BufferedOutputStream bufferOut = new BufferedOutputStream(fout, buffer.length);
while ((size = is.read(buffer, 0, buffer.length)) != -1) {
bufferOut.write(buffer, 0, size);
}
bufferOut.flush();
bufferOut.close();
is.close();
fout.close();
}
I am doing a simple android application which consists of compressing folder. Actually the compression process is completed and the file is saved in the defined location. But the problem is when i push the zipped file from the emulator and unzipping it manually the files are corrupted. What's the problem. Is the file become corrupted when we unzip manually?
My folder structure is given below
TestPlay1- contains two sub directories - playlist and content
the directory playlist contains a xml file
the directory content contains files such as images and videos
My code is given below
String zipFile = "/mnt/sdcard/Testplay1.zip";
byte[] buffer = new byte[1024];
FileOutputStream fos = null;
try {
fos = new FileOutputStream(zipFile);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
ZipOutputStream zos = new ZipOutputStream(fos);
updata = new ArrayList<File>();
contentpath = new File(FOLDER_PATH);
try {
if (contentpath.isDirectory()) {
File[] listFile = contentpath.listFiles();
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
File[] contfile = listFile[i].listFiles();
for (int j = 0; j < contfile.length; j++) {
updata.add(contfile[j]);
FileInputStream fis = new FileInputStream(contfile[j]);
zos.putNextEntry(new ZipEntry(contfile[j].getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
// close the InputStream
fis.close();
}
}
}
zos.close();
}
System.out.println("Testplay1 Folder contains=>" + updata);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
I suggest you to use Zip4j: http://www.lingala.net/zip4j/
There you can just put the Folder to compress and the rest is done by the library
ZipFile zipfile = new ZipFile("/mnt/sdcard/bla.zip");
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
zipfile.addFolder("/mnt/sdcard/folderToZip", parameters);