Search code examples
androidepubepub3

unzipping ePub file doesn't work


I am developping an app to decompress an .epub file into SDCARD in Android. I already read the Can't Unzip EPub File TOPIC. IT WORKED FOR .zip files but not for .epub files. Can somone tell me where is the problem ? here is the exception log:

03-21 13:35:44.281: W/System.err(1255): java.io.FileNotFoundException: /mnt/sdcard/unzipped11/META-INF/container.xml: open failed: ENOENT (No such file or directory)

I am using this code:

private void decom() throws IOException {
    ZipFile zipFile = new ZipFile(Environment.getExternalStorageDirectory()+"/dir.zip");
    String path = Environment.getExternalStorageDirectory() + "/unzipped10/";

    Enumeration<?> files = zipFile.entries();
    _dirChecker("");
    while (files.hasMoreElements()) {
        ZipEntry entry = (ZipEntry) files.nextElement();
        Log.v("ZipEntry", ""+entry);
        Log.v("isDirectory", ""+entry.isDirectory());

        if (entry.isDirectory()) {
            File file = new File(path + entry.getName());
            file.mkdir();
            System.out.println("Create dir " + entry.getName());
        } else {
            File f = new File(path + entry.getName());
            FileOutputStream fos = new FileOutputStream(f);
            InputStream is = zipFile.getInputStream(entry);
            byte[] buffer = new byte[1024];
            int bytesRead = 0;
            while ((bytesRead = is.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
            fos.close();
            System.out.println("Create File " + entry.getName());
        }
    }
}

Solution

  • Based on your response to my comment, it sounds like the parent directory to the file is not created before the entry for the file in the archive is attempted to be written.

    It sounds like you may need to alter the code that deals with a file entry in the zip file to create parent directories if they do not yet exist. You may also need to alter the code which creates the directories to check if the directory already exists before creating it.

    Try something like this:

        while (files.hasMoreElements()) {
            ZipEntry entry = (ZipEntry) files.nextElement();
            Log.d(TAG, "ZipEntry: "+entry);
            Log.d(TAG, "isDirectory: " + entry.isDirectory());
    
            if (entry.isDirectory()) {
                File file = new File(path + entry.getName());
                file.mkdir();
                Log.d(TAG, "Create dir " + entry.getName());
            } else {
                File f = new File(path + entry.getName());
                f.getParentFile().mkdirs();
                FileOutputStream fos = new FileOutputStream(f);
                InputStream is = zipFile.getInputStream(entry);
                byte[] buffer = new byte[1024];
                int bytesRead = 0;
                while ((bytesRead = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                }
                fos.close();
                Log.d(TAG, "Create File " + entry.getName());
            }
        }
        Log.d(TAG, "Done extracting epub file");
    

    For me this produces the following output using a test epub (moby dick from Google's epub samples: https://code.google.com/p/epub-samples/downloads/list)

    ZipEntry: mimetype
    isDirectory: false
    Create File mimetype
    ZipEntry: META-INF/
    isDirectory: true
    Create dir META-INF/
    ZipEntry: META-INF/container.xml
    isDirectory: false
    Create File META-INF/container.xml
    ZipEntry: OPS/
    isDirectory: true
    Create dir OPS/
    ZipEntry: OPS/chapter_001.xhtml
    isDirectory: false
    Create File OPS/chapter_001.xhtml
    ZipEntry: OPS/chapter_002.xhtml
    isDirectory: false
    Create File OPS/chapter_002.xhtml
    ZipEntry: OPS/chapter_003.xhtml
    isDirectory: false
    ...
    Create File OPS/toc-short.xhtml
    ZipEntry: OPS/toc.xhtml
    isDirectory: false
    Create File OPS/toc.xhtml
    Done extracting epub file