首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Android中下载和解压Zip文件

在Android中下载和解压Zip文件
EN

Stack Overflow用户
提问于 2012-02-17 14:53:06
回答 3查看 76.6K关注 0票数 26

我的应用程序正在从服务器下载zip文件并提取此zip文件并将文件保存到SD卡中,但问题是如果我正在下载4-5MB的zip文件并将其解压缩,这工作正常,但如果我正在下载30-35MB的zip文件,这将给我错误,为我糟糕的英语沟通道歉。

以下是我下载和解压Zip文件的代码:

代码语言:javascript
复制
public class UnzipManager {
    private static String BASE_FOLDER;

    public static Context localContext;
    public static String passurl;
    public static int count;
    public static Context context;
    /*
     * You can use this flag to check whether Unzippingthread is still running..
     */
    public static boolean isDownloadInProgress;
    /*
     * After unzipping using this flag ,you can check whether any low memory
     * exceptions Occurred or not..and alert user accordingly..
     */
    public static boolean isLowOnMemory;
    public static int i = 0;

    public static ZipEntry zipEntry;

    public static void startUnzipping(Context ctx, int c, String url) {
        context = ctx;
        count = c;
        /*
         * MAKE SURE THAT localContext VARIABLE HAS BEEN INITIALIZED BEFORE
         * INVOKING THIS METHOD.
         * 
         * ALSO MAKE SURE YOU HAVE SET "INTERNET" AND "NETWORK ACCESS STATE"
         * PERMISSIONS IN APPLICATION'S MANIFEST FILE.
         */
        Log.d("DEBUG", "In startUnzipping()");
        UnzipManager.BASE_FOLDER = Environment.getExternalStorageDirectory()
                + File.separator + "samples";
        /*
         *
         */

        Log.d("DEBUG", "BASE_FOLDER:" + UnzipManager.BASE_FOLDER);
        UnzipManager.isLowOnMemory = false;
        // Start unzipping in a thread..which is safer
        // way to do high cost processes..
        passurl = url;
        new UnzipThread().start();
    }

    private static class UnzipThread extends Thread {
        @Override
        public void run() {
            UnzipManager.isDownloadInProgress = true;
            Log.d("DEBUG", "Unzipping----------------------------");
            URLConnection urlConnection;
            try {
                /************************************************
                 * 
                 * IF you are unzipping a zipped file save under some URL in
                 * remote server
                 * **********************************************/
                URL finalUrl = new URL(passurl
                /* Url string where the zipped file is stored... */);
                urlConnection = finalUrl.openConnection();

                // Get the size of the ( zipped file's) inputstream from
                // server..
                int contentLength = urlConnection.getContentLength();
                Log.d("DEBUG", "urlConnection.getContentLength():"
                        + contentLength);
                /*****************************************************
                 * 
                 * YOU CAN GET INPUT STREAM OF A ZIPPED FILE FROM ASSETS FOLDER
                 * AS WELL..,IN THAT CASE JUST PASS THAT INPUTSTEAM OVER
                 * HERE...MAKE SURE YOU HAVE SET STREAM CONTENT LENGTH OF THE
                 * SAME..
                 * 
                 ******************************************************/
                ZipInputStream zipInputStream = new ZipInputStream(
                        urlConnection.getInputStream());
                /*
                 * Iterate over all the files and folders
                 */
                for (zipEntry = zipInputStream.getNextEntry(); zipEntry != null; zipEntry = zipInputStream
                        .getNextEntry()) {
                    Log.d("DEBUG", "Extracting: " + zipEntry.getName() + "...");

                    /*
                     * Extracted file will be saved with same file name that in
                     * zipped folder.
                     */


                    String innerFileName = BASE_FOLDER + File.separator
                            + zipEntry.getName();
                    File innerFile = new File(innerFileName);

                    /*
                     * Checking for pre-existence of the file and taking
                     * necessary actions
                     */
                    if (innerFile.exists()) {
                        Log.d("DEBUG",
                                "The Entry already exits!, so deleting..");
                        innerFile.delete();
                    }

                    /*
                     * Checking for extracted entry for folder type..and taking
                     * necessary actions
                     */
                    if (zipEntry.isDirectory()) {
                        Log.d("DEBUG", "The Entry is a directory..");
                        innerFile.mkdirs();
                    } else {
                        Log.d("DEBUG", "The Entry is a file..");
                        FileOutputStream outputStream = new FileOutputStream(
                                innerFileName);
                        final int BUFFER_SIZE = 2048;

                        /*
                         * Get the buffered output stream..
                         */
                        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                                outputStream, BUFFER_SIZE);
                        /*
                         * Write into the file's buffered output stream ,..
                         */
                        int count = 0;
                        byte[] buffer = new byte[BUFFER_SIZE];
                        while ((count = zipInputStream.read(buffer, 0,
                                BUFFER_SIZE)) != -1) {
                            bufferedOutputStream.write(buffer, 0, count);
                        }
                        /***********************************************
                         * IF YOU WANT TO TRACK NO OF FILES DOWNLOADED, HAVE A
                         * STATIC COUNTER VARIABLE, INITIALIZE IT IN
                         * startUnzipping() before calling startUnZipping(), AND
                         * INCREMENT THE COUNTER VARIABLE OVER HERE..LATER YOU
                         * CAN USE VALUE OF COUNTER VARIABLE TO CROSS VERIFY
                         * WHETHER ALL ZIPPED FILES PROPERLY UNZIPPED AND SAVED
                         * OR NOT.
                         * 
                         * ************************************************
                         */
                        /*
                         * Handle closing of output streams..
                         */
                        bufferedOutputStream.flush();
                        bufferedOutputStream.close();
                    }
                    /*
                     * Finish the current zipEntry
                     */
                    zipInputStream.closeEntry();
                }
                /*
                 * Handle closing of input stream...
                 */
                zipInputStream.close();
                Log.d("DEBUG", "--------------------------------");
                Log.d("DEBUG", "Unzipping completed..");
                i = 1;

            } catch (IOException e) {
                Log.d("DEBUG", "Exception occured: " + e.getMessage());
                if (e.getMessage().equalsIgnoreCase("No space left on device")) {
                    UnzipManager.isLowOnMemory = true;
                }
                e.printStackTrace();
            }

            MainActivity.pd.dismiss();

            ((MainActivity)context).finish();       

            UnzipManager.isDownloadInProgress = false;
        }
    };
}

Logcat错误为:-

代码语言:javascript
复制
02-17 12:21:16.835: D/DEBUG(20562): Exception occured: /mnt/sdcard/samples/iPhone_zendura_Q4a/0.png (No such file or directory)
02-17 12:21:16.835: W/System.err(20562): java.io.FileNotFoundException: /mnt/sdcard/samples/iPhone_zendura_Q4a/0.png (No such file or directory)
02-17 12:21:16.906: W/System.err(20562):    at org.apache.harmony.luni.platform.OSFileSystem.open(Native Method)
02-17 12:21:16.906: W/System.err(20562):    at dalvik.system.BlockGuard$WrappedFileSystem.open(BlockGuard.java:232)
02-17 12:21:16.906: W/System.err(20562):    at java.io.FileOutputStream.<init>(FileOutputStream.java:94)
02-17 12:21:16.906: W/System.err(20562):    at java.io.FileOutputStream.<init>(FileOutputStream.java:165)
02-17 12:21:16.906: W/System.err(20562):    at java.io.FileOutputStream.<init>(FileOutputStream.java:144)
02-17 12:21:16.906: W/System.err(20562):    at com.android.screens.UnzipManager$UnzipThread.run(UnzipManager.java:129)
EN

回答 3

Stack Overflow用户

发布于 2012-02-17 18:14:52

正如JoxTraex所说:错误真的很明显。

UnzipManager的129行,您试图打开一个不存在的文件。这就是为什么你会得到一个FileNotFoundException。您应该检查您的压缩文件,如果它是一个正确的文件,并可以在您的PC上正确解压。

也试着调试一下。在该行上添加一个断点,让应用程序调试并观察当特定文件位置出现时会发生什么。

票数 5
EN

Stack Overflow用户

发布于 2013-01-31 06:12:41

如果文件存在,不要删除(因为文件将被覆盖)或再次实例化innerFile。

代码语言:javascript
复制
if (innerFile.exists()) {
         Log.d("DEBUG",
               "The Entry already exits!, so deleting..");
         innerFile.delete();
}

//Instantiate Again
innerFile = new File(innerFileName);

删除innerFile会丢失文件,并且在尝试使用innerFile创建目录时会导致FileNotFoundException。

票数 2
EN

Stack Overflow用户

发布于 2015-06-03 04:27:29

这是使用performance improvement answer的最终代码,它在1分钟内将一个23 MB的文件解压缩到一个130 MB的文件夹中:

代码语言:javascript
复制
public class Decompress {
private String _zipFile;
private String _location;

public Decompress(String zipFile, String location) {
    _zipFile = zipFile;
    _location = location;

    _dirChecker("");
}

public void unzip() {
    try  {
        FileInputStream fin = new FileInputStream(_zipFile);
        ZipInputStream zin = new ZipInputStream(fin);

        byte b[] = new byte[1024];

        ZipEntry ze = null;
        while ((ze = zin.getNextEntry()) != null) {
            Log.v("Decompress", "Unzipping " + ze.getName());

            if(ze.isDirectory()) {
                _dirChecker(ze.getName());
            } else {
                FileOutputStream fout = new FileOutputStream(_location + ze.getName());

                BufferedInputStream in = new BufferedInputStream(zin);
                BufferedOutputStream out = new BufferedOutputStream(fout);

                int n;
                while ((n = in.read(b,0,1024)) >= 0) {
                    out.write(b,0,n);
                }

                zin.closeEntry();
                out.close();
            }

        }
        zin.close();
    } catch(Exception e) {
        Log.e("Decompress", "unzip", e);
    }

}

private void _dirChecker(String dir) {
    File f = new File(_location + dir);

    if(!f.isDirectory()) {
        f.mkdirs();
    }
}}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9324103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档