Entreco
Entreco

Reputation: 12900

Android unzipping files that where zipped on a Mac

I have an application, which downloads a zip and unzips the files on my SDCard. All works fine, but when my collegue creates the zip file on his Mac (lion), all my files have

size:-1

crc:-1

compressedsize:-1

and I cannot write the files to my sdcard. Both zips have exactly the same content, the only difference is where they where originally zipped. This is the code where I unzip the files:

public class UnzipTask extends AsyncTask<String, Integer, Void> {

    private static final String TAG = UnzipTask.class.getSimpleName();


    private String mDestLocation;
    private ZipListener mListener;
    private Context mCtx;

    private int mCallbackId;

    public UnzipTask(Context context, ZipListener listener, File dir)
    {
        mCtx = context;
        mListener = listener;
        mDestLocation = dir.getAbsolutePath() + "/";

    }

    public void setId(int id)
    {
        mCallbackId = id;
    }

    @Override
    protected Void doInBackground(String... arg0) {


        try {

            String file = arg0[0];
            InputStream is = mCtx.getAssets().open(file);
            unzipFile(is);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * Private function that ensures a directory exist
     * @param dir
     */
    private void _dirChecker(String dir) {
        File f = new File(mDestLocation + dir);

        if (!f.isDirectory()) {
            f.mkdirs();
            }
    }

    private void unzipFile(InputStream input) throws Exception {

        ZipInputStream zin = new ZipInputStream(input);
        ZipEntry ze = null;

        while ((ze = zin.getNextEntry()) != null) {

            Log.v(TAG, "Unzipping " + ze.getName());

            if(mListener != null)
            {
                mListener.onUnzipped(mCallbackId, ze.getName(), ze.g   etSize(), ze.getCrc(), ze.getCompressedSize());
                }

            if (ze.isDirectory()) {
                _dirChecker(ze.getName());
            } else if (ze.getCompressedSize() > 0 && ze.getSize() > 0 && ze.getCrc() != 0.0) {
                // If size=-1 -> writing to disk fails

                String fileOutput = mDestLocation + ze.getName();

                FileOutputStream fout = new FileOutputStream(fileOutput);
                int read = 0;

                byte[] buffer = new byte[(int) ze.getSize()];

                while ((read = zin.read(buffer)) >= 0) {
                    fout.write(buffer, 0, read);
                }

                zin.closeEntry();
                fout.close();
                } else {
                Log.v(TAG, "Skipping entry" + ze.getName());
            } 
            }
        }

        zin.close();
    }

}

A couple of notes

1) I can unzip both files on my windows 7 pc

2) My collegue can unzip both files on his Mac

3) The only problem is, on Android I cannot unzip the zip file the MAC creates...

QUESTION:

Does anyone know why the zip file that was zipped on a Mac has these invalid sizes? Is my Unzipping process (on Android) missing some code?

You can download the zips here if you want, as well as a very small apk to show the output:

EDIT: updated the links

Zip file (zipped on a Mac)

Zip file (zippen on Win7)

Demo.apk

Upvotes: 4

Views: 2726

Answers (2)

devunwired
devunwired

Reputation: 63293

The issue relates to version. Let me start with some output from my Mac (10.8):

~ $ zipinfo -m test_mac.zip 
Archive: test_mac.zip   1694 bytes   8 files
drwxr-xr-x  2.1 unx        0 bx  0% stor 10-Aug-12 01:11 test_win/
-rwxr-xr-x  2.1 unx       46 bX 20% defN 10-Aug-12 01:11 test_win/index.html
drwxrwxr-x  2.1 unx        0 bx  0% stor 10-Aug-12 01:12 __MACOSX/
drwxrwxr-x  2.1 unx        0 bx  0% stor 10-Aug-12 01:12 __MACOSX/test_win/
-rw-r--r--  2.1 unx      211 bX 37% defN 10-Aug-12 01:11 __MACOSX/test_win/._index.html
-rwxr-xr-x  2.1 unx        9 bX-21% defN 10-Aug-12 01:10 test_win/version.txt
-rw-r--r--  2.1 unx      211 bX 37% defN 10-Aug-12 01:10 __MACOSX/test_win/._version.txt
-rw-r--r--  2.1 unx      211 bX 37% defN 10-Aug-12 01:11 __MACOSX/._test_win
8 files, 688 bytes uncompressed, 450 bytes compressed:  34.6%
~ $ zipinfo -m test_win.zip 
Archive: test_win.zip   1678 bytes   8 files
drwx---     3.1 fat        0 bx  0% stor 10-Aug-12 09:11 test_win/
-rw-a--     3.1 fat       46 bx 20% defN 10-Aug-12 09:11 test_win/index.html
-rw-a--     3.1 fat        9 bx-21% defN 10-Aug-12 09:10 test_win/version.txt
drwx---     3.1 fat        0 bx  0% stor 10-Aug-12 09:12 __MACOSX/
-rw-a--     3.1 fat      211 bx 37% defN 10-Aug-12 09:11 __MACOSX/._test_win
drwx---     3.1 fat        0 bx  0% stor 10-Aug-12 09:12 __MACOSX/test_win/
-rw-a--     3.1 fat      211 bx 37% defN 10-Aug-12 09:11 __MACOSX/test_win/._index.html
-rw-a--     3.1 fat      211 bx 37% defN 10-Aug-12 09:10 __MACOSX/test_win/._version.txt
8 files, 688 bytes uncompressed, 450 bytes compressed:  34.6%

Have a look at the second field (2.1 in the mac file and 3.1 in the win file). This is the ZIP archive format version that the file was compressed against. The java.util.zip implementation only supports version 2.50 and higher of the ZIP file format (See this StackOverflow).

The Mac's Compress ... menu option uses a version below what the Java implementation supports (2.1 is still used in 10.8 as well).

Tell your colleague to use the command line tool instead (e.g. zip -r myfile.zip directory_to_compress/) and you should get an output that the Android application can inflate.

Upvotes: 5

nielsbot
nielsbot

Reputation: 16022

These files are very different... Hard to look for important differences.enter image description here

Upvotes: 0

Related Questions