it-swarm.com.de

Laden Sie die Zip-Datei in Android herunter und extrahieren Sie sie

Meine Anwendung lädt Zip-Dateien vom Server herunter und entpackt diese Zip-Datei und speichert Dateien auf der SD-Karte. Das Problem ist jedoch, wenn ich 4-5 MB Zip-Dateien herunterlade und diese entpacke Zip-Datei Dies gibt mir einen Fehler, sorry für meine schlechte englische Kommunikation.

Im Folgenden finden Sie meinen Code zum Herunterladen und Entpacken der Zip-Datei: -

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-Fehler ist: -

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)
27
Dipak Keshariya

Ich habe einen IntentService geschrieben, der beide Dinge zusammen mit dem Fortschritt dosiert:

Fügen Sie Ihrer Anwendung die folgende Service-Klasse hinzu (deklarieren Sie sie auch in der Manifest-Datei Ihrer App):  

import Android.app.IntentService;
import Android.content.Context;
import Android.content.Intent;
import Android.net.ConnectivityManager;
import Android.net.NetworkInfo;
import Android.os.Bundle;
import Android.os.Handler;
import Android.os.Looper;
import Android.os.Parcel;
import Android.os.Parcelable;
import Android.os.ResultReceiver;
import Android.util.Log;

import Java.io.BufferedInputStream;
import Java.io.BufferedOutputStream;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.OutputStream;
import Java.net.URL;
import Java.net.URLConnection;
import Java.util.Enumeration;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipFile;

/**
 * Created by Vaibhav.Jani on 6/4/15.
 */
public class FileDownloadService extends IntentService {

    private static int STATUS_OK = 100;

    private static int STATUS_FAILED = 200;

    private static final String DOWNLOADER_RECEIVER = "downloader_receiver";

    private static final String DOWNLOAD_DETAILS = "download_details";

    private static final String DOWNLOAD_STARTED = "download_started";

    private static final String DOWNLOAD_FAILED = "download_failed";

    private static final String DOWNLOAD_COMPLETED = "download_completed";

    private static final String DOWNLOAD_PROGRESS = "download_progress";

    public FileDownloadService() {

        super("");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        Bundle bundle = intent.getExtras();

        if (bundle == null
                || !bundle.containsKey(DOWNLOADER_RECEIVER)
                || !bundle.containsKey(DOWNLOAD_DETAILS)) {

            return;
        }

        ResultReceiver resultReceiver = bundle.getParcelable(DOWNLOADER_RECEIVER);

        DownloadRequest downloadDetails = bundle.getParcelable(DOWNLOAD_DETAILS);

        try {

            assert downloadDetails != null;
            URL url = new URL(downloadDetails.getServerFilePath());

            URLConnection urlConnection = url.openConnection();

            urlConnection.connect();

            int lengthOfFile = urlConnection.getContentLength();

            Log.d("FileDownloaderService", "Length of file: " + lengthOfFile);
            downloadStarted(resultReceiver);

            InputStream input = new BufferedInputStream(url.openStream());

            String localPath = downloadDetails.getLocalFilePath();

            OutputStream output = new FileOutputStream(localPath);

            byte data[] = new byte[1024];

            long total = 0;

            int count;

            while ((count = input.read(data)) != -1) {

                total += count;

                int progress = (int) ((total * 100) / lengthOfFile);

                sendProgress(progress, resultReceiver);

                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();

            if (downloadDetails.isRequiresUnzip()) {

                String unzipDestination = downloadDetails.getUnzipAtFilePath();

                if(unzipDestination == null){

                    File file = new File(localPath);

                    unzipDestination = file.getParentFile().getAbsolutePath();
                }

                unzip(localPath, unzipDestination);
            }

            downloadCompleted(resultReceiver);

            if (downloadDetails.isDeleteZipAfterExtract()) {

                File file = new File(localPath);
                file.delete();
            }

        } catch (Exception e) {

            e.printStackTrace();

            downloadFailed(resultReceiver);
        }

    }

    public void sendProgress(int progress, ResultReceiver receiver) {

        Bundle progressBundle = new Bundle();
        progressBundle.putInt(FileDownloadService.DOWNLOAD_PROGRESS, progress);
        receiver.send(STATUS_OK, progressBundle);
    }

    public void downloadStarted(ResultReceiver resultReceiver) {

        Bundle progressBundle = new Bundle();
        progressBundle.putBoolean(FileDownloadService.DOWNLOAD_STARTED, true);
        resultReceiver.send(STATUS_OK, progressBundle);
    }

    public void downloadCompleted(ResultReceiver resultReceiver) {

        Bundle progressBundle = new Bundle();
        progressBundle.putBoolean(FileDownloadService.DOWNLOAD_COMPLETED, true);
        resultReceiver.send(STATUS_OK, progressBundle);
    }

    public void downloadFailed(ResultReceiver resultReceiver) {

        Bundle progressBundle = new Bundle();
        progressBundle.putBoolean(FileDownloadService.DOWNLOAD_FAILED, true);
        resultReceiver.send(STATUS_FAILED, progressBundle);
    }

    private void unzip(String zipFilePath, String unzipAtLocation) throws Exception {

        File archive = new File(zipFilePath);

        try {

            ZipFile zipfile = new ZipFile(archive);

            for (Enumeration e = zipfile.entries(); e.hasMoreElements(); ) {

                ZipEntry entry = (ZipEntry) e.nextElement();

                unzipEntry(zipfile, entry, unzipAtLocation);
            }

        } catch (Exception e) {

            Log.e("Unzip Zip", "Unzip exception", e);
        }
    }

    private void unzipEntry(ZipFile zipfile, ZipEntry entry, String outputDir) throws IOException {

        if (entry.isDirectory()) {
            createDir(new File(outputDir, entry.getName()));
            return;
        }

        File outputFile = new File(outputDir, entry.getName());
        if (!outputFile.getParentFile().exists()) {
            createDir(outputFile.getParentFile());
        }

        Log.v("Zip E", "Extracting: " + entry);

        InputStream zin = zipfile.getInputStream(entry);
        BufferedInputStream inputStream = new BufferedInputStream(zin);
        BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));

        try {

            //IOUtils.copy(inputStream, outputStream);

            try {

                for (int c = inputStream.read(); c != -1; c = inputStream.read()) {
                    outputStream.write(c);
                }

            } finally {

                outputStream.close();
            }

        } finally {
            outputStream.close();
            inputStream.close();
        }
    }

    private void createDir(File dir) {

        if (dir.exists()) {
            return;
        }

        Log.v("Zip E", "Creating dir " + dir.getName());

        if (!dir.mkdirs()) {

            throw new RuntimeException("Can not create dir " + dir);
        }
    }

    public static class FileDownloader extends ResultReceiver {

        private DownloadRequest downloadDetails;

        private OnDownloadStatusListener onDownloadStatusListener;

        public static FileDownloader getInstance(DownloadRequest downloadDetails, OnDownloadStatusListener downloadStatusListener) {

            Handler handler = new Handler(Looper.getMainLooper());

            FileDownloader fileDownloader = new FileDownloader(handler);

            fileDownloader.downloadDetails = downloadDetails;

            fileDownloader.onDownloadStatusListener = downloadStatusListener;

            return fileDownloader;
        }

        public void download(Context context) {

            if (isOnline(context)) {

                Intent intent = new Intent(context, FileDownloadService.class);
                intent.putExtra(FileDownloadService.DOWNLOADER_RECEIVER, this);
                intent.putExtra(FileDownloadService.DOWNLOAD_DETAILS, downloadDetails);
                context.startService(intent);
            }
        }

        private FileDownloader(Handler handler) {

            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {

            super.onReceiveResult(resultCode, resultData);

            if (onDownloadStatusListener == null) {

                return;
            }

            if (resultCode == FileDownloadService.STATUS_OK) {

                if (resultData.containsKey(FileDownloadService.DOWNLOAD_STARTED)
                        && resultData.getBoolean(FileDownloadService.DOWNLOAD_STARTED)) {

                    onDownloadStatusListener.onDownloadStarted();

                } else if (resultData.containsKey(FileDownloadService.DOWNLOAD_COMPLETED)
                        && resultData.getBoolean(FileDownloadService.DOWNLOAD_COMPLETED)) {

                    onDownloadStatusListener.onDownloadCompleted();

                } else if (resultData.containsKey(FileDownloadService.DOWNLOAD_PROGRESS)) {

                    int progress = resultData.getInt(FileDownloadService.DOWNLOAD_PROGRESS);
                    onDownloadStatusListener.onDownloadProgress(progress);

                }

            } else if (resultCode == FileDownloadService.STATUS_FAILED) {

                onDownloadStatusListener.onDownloadFailed();
            }
        }

        public DownloadRequest getDownloadDetails() {

            return downloadDetails;
        }

        public void setDownloadDetails(DownloadRequest downloadDetails) {

            this.downloadDetails = downloadDetails;
        }

        public OnDownloadStatusListener getOnDownloadStatusListener() {

            return onDownloadStatusListener;
        }

        public void setOnDownloadStatusListener(OnDownloadStatusListener onDownloadStatusListener) {

            this.onDownloadStatusListener = onDownloadStatusListener;
        }

    }

    public static interface OnDownloadStatusListener {

        void onDownloadStarted();

        void onDownloadCompleted();

        void onDownloadFailed();

        void onDownloadProgress(int progress);

    }

    public static class DownloadRequest implements Parcelable {

        private String tag;

        private boolean requiresUnzip;

        private String serverFilePath;

        private String localFilePath;

        private String unzipAtFilePath;

        private boolean deleteZipAfterExtract = true;

        public DownloadRequest(String serverFilePath, String localPath) {

            this.serverFilePath = serverFilePath;

            this.localFilePath = localPath;

            this.requiresUnzip = requiresUnzip;
        }

        protected DownloadRequest(Parcel in) {

            requiresUnzip = in.readByte() != 0x00;
            serverFilePath = in.readString();
            localFilePath = in.readString();
            unzipAtFilePath = in.readString();
            deleteZipAfterExtract = in.readByte() != 0x00;
        }

        @Override
        public int describeContents() {

            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {

            dest.writeByte((byte) (requiresUnzip ? 0x01 : 0x00));
            dest.writeString(serverFilePath);
            dest.writeString(localFilePath);
            dest.writeString(unzipAtFilePath);
            dest.writeByte((byte) (deleteZipAfterExtract ? 0x01 : 0x00));
        }

        @SuppressWarnings("unused")
        public static final Parcelable.Creator<DownloadRequest> CREATOR = new Parcelable.Creator<DownloadRequest>() {

            @Override
            public DownloadRequest createFromParcel(Parcel in) {

                return new DownloadRequest(in);
            }

            @Override
            public DownloadRequest[] newArray(int size) {

                return new DownloadRequest[size];
            }
        };

        public boolean isRequiresUnzip() {

            return requiresUnzip;
        }

        public void setRequiresUnzip(boolean requiresUnzip) {

            this.requiresUnzip = requiresUnzip;
        }

        public String getServerFilePath() {

            return serverFilePath;
        }

        public void setServerFilePath(String serverFilePath) {

            this.serverFilePath = serverFilePath;
        }

        public String getLocalFilePath() {

            return localFilePath;
        }

        public void setLocalFilePath(String localFilePath) {

            this.localFilePath = localFilePath;
        }

        public static Creator<DownloadRequest> getCreator() {

            return CREATOR;
        }

        public String getUnzipAtFilePath() {
            return unzipAtFilePath;
        }

        public void setUnzipAtFilePath(String unzipAtFilePath) {
            this.unzipAtFilePath = unzipAtFilePath;
        }

        public String getTag() {
            return tag;
        }

        public void setTag(String tag) {
            this.tag = tag;
        }

        public boolean isDeleteZipAfterExtract() {
            return deleteZipAfterExtract;
        }

        public void setDeleteZipAfterExtract(boolean deleteZipAfterExtract) {
            this.deleteZipAfterExtract = deleteZipAfterExtract;
        }
    }

    private static boolean isOnline(Context context) {

        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo netInfo = cm.getActiveNetworkInfo();

        if (netInfo != null
                && netInfo.isConnectedOrConnecting()
                && cm.getActiveNetworkInfo().isAvailable()
                && cm.getActiveNetworkInfo().isConnected()) {

            return true;
        }

        return false;
    }

}

Anwendungsbeispiel:

String serverFilePath = "http://www.colorado.edu/conflict/peace/download/peace_problem.Zip";

String path = FileUtils.getDataDir(context).getAbsolutePath();

String fileName = "sample_download";
File file = new File(path, fileName);

String localPath = file.getAbsolutePath();
String unzipPath = FileUtils.getDataDir(context, "ExtractLoc").getAbsolutePath();

FileDownloadService.DownloadRequest downloadRequest = new FileDownloadService.DownloadRequest(serverFilePath, localPath);
downloadRequest.setRequiresUnzip(true);
downloadRequest.setDeleteZipAfterExtract(false);
downloadRequest.setUnzipAtFilePath(unzipPath);

FileDownloadService.OnDownloadStatusListener listener = new FileDownloadService.OnDownloadStatusListener() {

    @Override
    public void onDownloadStarted() {
    }

    @Override
    public void onDownloadCompleted() {
    }

    @Override
    public void onDownloadFailed() {
    }

    @Override
    public void onDownloadProgress(int progress) {
    }
};

FileDownloadService.FileDownloader downloader = FileDownloadService.FileDownloader.getInstance(downloadRequest, listener);
downloader.download(context);

Sie können auch (falls erforderlich) FileUtils.Java verwenden

import Android.content.Context;

import Java.io.File;

public class FileUtils {

    public static File getDataDir(Context context) {

        String path = context.getFilesDir().getAbsolutePath() + "/SampleZip";

        File file = new File(path);

        if(!file.exists()) {

            file.mkdirs();
        }

        return file;
    }

    public static File getDataDir(Context context, String folder) {

        String path = context.getFilesDir().getAbsolutePath() + "/" + folder;

        File file = new File(path);

        if(!file.exists()) {

            file.mkdirs();
        }

        return file;
    }
}
9
Vaibhav Jani

Wie JoxTraex sagte: Der Fehler liegt auf der Hand.

In UnzipManager Zeile 129 versuchen Sie, eine Datei zu öffnen, die nicht vorhanden ist. Deshalb erhalten Sie eine FileNotFoundException. Sie sollten Ihre Zip-Datei überprüfen, wenn sie korrekt ist und auf Ihrem PC korrekt extrahiert werden kann.

Versuchen Sie auch zu debuggen. Fügen Sie einen Haltepunkt in dieser Zeile hinzu, und lassen Sie die Anwendung debuggen und beobachten Sie, was dort passiert, wenn der bestimmte Dateispeicherort angezeigt wird.

5
WarrenFaith

Löschen Sie die Datei nicht, wenn sie existiert (weil die Dateien überschrieben werden), oder instanziieren Sie innerFile erneut. 

if (innerFile.exists()) {
         Log.d("DEBUG",
               "The Entry already exits!, so deleting..");
         innerFile.delete();
}

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

Wenn Sie innerFile löschen, verlieren Sie die Datei. Wenn Sie versuchen, ein Verzeichnis mit innerFile zu erstellen, führt dies zu einer FileNotFoundException.

2
N20084753

Dies ist der endgültige Code, der die Antwort " performance improvement" verwendet , er dekomprimiert eine 23 MB-Datei in genau 1 Minute in einen 130 MB-Ordner:

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();
    }
}}
0