zip files portability on win and mac

G

gianpi

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) ;
}
} 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
 
J

Joshua Cranmer

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!
 
R

rossum

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
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
 
R

Roedy Green

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top