Hi,
I'm currently developing an application which, among other things,
should zip some folders with all their content (therefore, also
subfolders).
Browsing I found and slightly adapted the following code:
public class ZipUtil {
private ZipOutputStream cpZipOutputStream = null;
private String strSource = "";
private String strTarget = "";
private String strSubstring = "";
public void ZipDirectory (String dir2zip, String destFile){
strSource = dir2zip;
strTarget = destFile;
zip();
}
private void zip(){
try{
File cpFile = new File (strSource);
if (!cpFile.isFile() && !cpFile.isDirectory() ) {
System.out.println("\nSource file/directory Not Found!");
return;
}
if (cpFile.isDirectory()) {
strSubstring = strSource;
} else {
strSubstring = "";
}
FileOutputStream fos = new FileOutputStream(strTarget);
cpZipOutputStream = new ZipOutputStream(fos);
cpZipOutputStream.setLevel(9);
zipFiles(cpFile);
cpZipOutputStream.finish();
cpZipOutputStream.close();
fos.close();
}catch (Exception e){
e.printStackTrace();
}
}
private void zipFiles(File cpFile) {
if (cpFile.isDirectory()) {
File [] fList = cpFile.listFiles() ;
for (int i=0; i< fList.length; i++){
zipFiles(fList[i]) ;
}
} else {
try {
String strAbsPath = cpFile.getAbsolutePath();
String strZipEntryName ="";
if (!strSubstring.equals("") ){
strZipEntryName = strAbsPath.substring(
strSource.length()+1, strAbsPath.length());
} else {
strZipEntryName = cpFile.getName();
}
byte[] b = new byte[ (int)(cpFile.length()) ];
FileInputStream cpFileInputStream =
new FileInputStream (cpFile) ;
cpFileInputStream.read(b, 0, (int)cpFile.length());
ZipEntry cpZipEntry = new ZipEntry(strZipEntryName);
cpZipOutputStream.putNextEntry(cpZipEntry );
cpZipOutputStream.write(b, 0, (int)cpFile.length());
cpZipOutputStream.closeEntry() ;
cpFileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The problem is that when I run this on Windows, the following line:
strZipEntryName = strAbsPath.substring(strSource.length()+1,
strAbsPath.length());
uses the backslash as File.separator. So the zip file contains all the
folders and subfolders when I extract the zip file on Windows.
On the other hand, if I try to extract on a Mac, it will consider the
backslash as part of the filename.
e.g.
folder\foo.bar
On Windows it's a folder with a foo.bar file inside.
On Mac, it is a file named "folder\foo".
Am I wrong somewhere, or is there any workaround for this problem?
I'd like my zip files to be as portable as my application :)
Thanks in advance for your answer!
gianpi
Joshua Cranmer - 16 Aug 2007 23:03 GMT
>> System.out.println("\nSource file/directory Not Found!");
Typically, errors should be using System.err, not System.out
> e.g.
> folder\foo.bar
>
> On Windows it's a folder with a foo.bar file inside.
> On Mac, it is a file named "folder\foo".
I take it that this is view from inside the zip file.
> Am I wrong somewhere, or is there any workaround for this problem?
I'm rusty on my ZIP file specification, but I believe that the file
separator is unambiguously "\", so there are two solutions:
1. Do a .replaceAll(File.separator, "\\") on the path name before you
put it in, or
2. Slightly refactor your code:
zip() {
if file is a directory
zipDir(file,"");
else
zipFile(file,"");
}
zipDir(File dir, String path) {
for all files
if file is directory, zipDir(file,path+dir.name())
else zipFile(file,path)
}
zipFile(File dir, String path) {
add to zip file
}
However, your code might run into problems with symlinked recursive
directories!

Signature
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
rossum - 16 Aug 2007 23:21 GMT
>The problem is that when I run this on Windows, the following line:
>
[quoted text clipped - 18 lines]
>
>gianpi
Have you had a look at File.pathSeparator, File.pathSeparatorChar,
File.separator and File.separatorChar ?
One or other of those should be able to help.
rossum
Roedy Green - 17 Aug 2007 02:37 GMT
>The problem is that when I run this on Windows, the following line:
>strZipEntryName = strAbsPath.substring(strSource.length()+1,
>strAbsPath.length())
When you examine the file with WinZip you will see \, but if you look
with a hex viewer, you will see /. You may well be ok.

Signature
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com