Android - 无法解压缩下载的zip文件 - UTFDataFormatException

时间:2017-01-10 02:39:35

标签: android utf-8 unzip

我目前正在开发一个Android应用程序,我在其中下载.zip存档然后解压缩它。存档的下载正确完成。我可以直接在手机或计算机上手动解压缩。

但是,当我尝试以编程方式解压缩归档时,我得到一个UTFDataFormatException。我尝试通过添加:

强制系统编码
System.setProperty("file.encoding", "UTF-8");

或者处理文件的名称:

filename = new String(ze.getName().getBytes("UTF-8"));

我的解压缩功能中是否遗漏了一些内容?

private boolean unzip(String path, String zipname)
{
    InputStream is;
    ZipInputStream zis;

    try
    {
        String filename;
        is = new FileInputStream(path + zipname);
        zis = new ZipInputStream(new BufferedInputStream(is));
        ZipEntry ze;
        byte[] buffer = new byte[4096];
        int count;

        while ((ze = zis.getNextEntry()) != null)
        {
            filename = ze.getName();

            if (ze.isDirectory())
            {
                File fmd = new File(path + filename);
                fmd.mkdirs();
                continue;
            }

            FileOutputStream fout = new FileOutputStream(path + filename);

            while ((count = zis.read(buffer)) != -1)
            {
                fout.write(buffer, 0, count);
            }

            fout.close();
            zis.closeEntry();
        }

        zis.close();
    }
    catch(IOException e)
    {
        e.printStackTrace();
        return false;
    }

    return true;
}

异常消息下方:

java.io.UTFDataFormatException: bad byte at 72

4 个答案:

答案 0 :(得分:0)

毕竟,我使用了Zip4j库,效果很好。这是一个旧库,由于gradle而无法维护且无法调用,但它解决了我的问题(http://www.lingala.net/zip4j/)。

try
{
    ZipFile zipFile = new ZipFile(sourceFile);
    zipFile.extractAll(destinationPath);
}
catch (ZipException e)
{
    e.printStackTrace();
}

答案 1 :(得分:-1)

试试这个:

 public static boolean unzip(String zipFile, String location) {
        if (!location.endsWith("/")) {
            location += "/";
        }

        if (!zipFile.endsWith(".zip") || !new File(location + zipFile).exists()) {
            return false;
        }
        int size;
        byte[] buffer = new byte[1024];
        try {
            File f = new File(location);
            if (!f.isDirectory()) {
                f.mkdirs();
            }
            ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(location + zipFile), 1024));
            try {
                ZipEntry ze = null;
                while ((ze = zin.getNextEntry()) != null) {
                    String path = location + ze.getName();
                    File unzipFile = new File(path);

                    if (ze.isDirectory()) {
                        if (!unzipFile.isDirectory()) {
                            unzipFile.mkdirs();
                        }
                    } else {
                        // check for and create parent directories if they don't exist
                        File parentDir = unzipFile.getParentFile();
                        if (null != parentDir) {
                            if (!parentDir.isDirectory()) {
                                parentDir.mkdirs();
                            }
                        }

                        // unzip the file
                        FileOutputStream out = new FileOutputStream(unzipFile, false);
                        BufferedOutputStream fout = new BufferedOutputStream(out, 1024);
                        try {
                            while ((size = zin.read(buffer, 0, 1024)) != -1) {
                                fout.write(buffer, 0, size);
                            }

                            zin.closeEntry();
                        } finally {
                            try {
                                fout.flush();
                                fout.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            } finally {
                try {
                    zin.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

答案 2 :(得分:-1)

试试这个,

public class DecompressZip{
private static final int BUFFER_SIZE=8192;

private String _zipFile;
private String _location;
private byte[] _buffer;

/**
 * Constructor.
 * 
 * @param zipFile       Fully-qualified path to .zip file
 * @param location      Fully-qualified path to folder where files should be written.
 *                      Path must have a trailing slash.
 */
public DecompressZip(String zipFile, String location)
{
    _zipFile = zipFile;
    _location = location;
    _buffer = new byte[BUFFER_SIZE];
    dirChecker("");
}

public void unzip()
{
    FileInputStream fin = null;
    ZipInputStream zin = null;
    OutputStream fout = null;

    File outputDir = new File(_location);
    File tmp = null;

    try {
        fin = new FileInputStream(_zipFile);
        zin = new ZipInputStream(fin);
        ZipEntry ze = null;

        while ((ze = zin.getNextEntry()) != null)
        {
            Log.d("Decompress", "Unzipping " + ze.getName());
            Log.d("Decompress", "FileSize " + ze.getSize());
            Log.d("Decompress", "compressedSize " + ze.getCompressedSize());

            if (ze.isDirectory())
            {
                dirChecker(ze.getName());
            }

            else
            {
                tmp = File.createTempFile( "decomp", ".tmp", outputDir );
                fout = new BufferedOutputStream(new FileOutputStream(tmp));
                DownloadFile.copyStream( zin, fout, _buffer, BUFFER_SIZE );
                zin.closeEntry();
                fout.close();
                fout = null;
                tmp.renameTo( new File(_location + ze.getName()) );
                tmp = null; 
            }
        }
        zin.close();
        zin = null;
    }

    catch (IOException e)
    {
        throw new RuntimeException(e);
    }

    finally
    {
        if ( tmp != null  ) { try { tmp.delete();     } catch (Exception ignore) {;} }
        if ( fout != null ) { try { fout.close();     } catch (Exception ignore) {;} }
        if ( zin != null  ) { try { zin.closeEntry(); } catch (Exception ignore) {;} }
        if ( fin != null  ) { try { fin.close();      } catch (Exception ignore) {;} }
    }
}

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

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

答案 3 :(得分:-1)

尝试以下代码。我这样做是为了下载压缩图像。

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.ParcelFileDescriptor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class MainActivity extends AppCompatActivity {

    private ProgressDialog simpleWaitDialog;
    private Bitmap table1,seat1,seat2,seat3,seat4,seat5,dummy;
    private ImageView tableIv,seat1Iv,seat2Iv,seat3Iv,seat4Iv,seat5Iv,overlay;
    File _zipFile;
    InputStream _zipFileStream;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tableIv=(ImageView)findViewById(R.id.iv);
        seat1Iv=(ImageView)findViewById(R.id.seat1IV);
        seat2Iv=(ImageView)findViewById(R.id.seat2IV);
        seat3Iv=(ImageView)findViewById(R.id.seat3IV);
        seat4Iv=(ImageView)findViewById(R.id.seat4IV);
        seat5Iv=(ImageView)findViewById(R.id.seat5IV);
        overlay=(ImageView)findViewById(R.id.overlayIV);
///data/user/0/com.example.ayyappaboddupalli.zipperunzipper/app_zipper1/themeparts1.zip/dummy/6_player.jpg -location where files stored

        ContextWrapper wrapper=new ContextWrapper(this);
        File sd = wrapper.getDir("zipper1", MODE_PRIVATE);
        File dest = new File(sd, "theme1.zip");
        File target = new File(sd, "themeparts1.zip");
        if(target.exists())
        {
            commonCaller(dest,target,sd);
        }
        else
        {
            new ImageDownloader().execute();

            commonCaller(dest,target,sd);
        }


    }
    private void uriToBitmap(Uri selectedFileUri, String name) {
        try {
            ParcelFileDescriptor parcelFileDescriptor =
                    getContentResolver().openFileDescriptor(selectedFileUri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            assignBitmapToView(image,name);


            parcelFileDescriptor.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void assignBitmapToView(Bitmap image, String name) {
        String toCompare=name.toString().substring(name.lastIndexOf("/")+1,name.lastIndexOf("."));
        switch (toCompare)
        {
            case "dummy":
                dummy=image;
                overlay.setImageBitmap(dummy);
                break;
            case "6_player":
                table1=image;
                tableIv.setImageBitmap(table1);
                break;
            case "f1":
                seat1=image;
                seat1Iv.setImageBitmap(seat1);
                break;
            case "f2":
                seat2=image;
                seat2Iv.setImageBitmap(seat2);

                break;
            case "f3":
                seat3=image;
                seat3Iv.setImageBitmap(seat3);

                break;
            case "f4":
                seat4=image;
                seat4Iv.setImageBitmap(seat4);

                break;
            case "f5":
                seat5=image;
                seat5Iv.setImageBitmap(seat5);

                break;



        }
    }

    public void commonCaller(File dest,File target,File sd)
    {
        if(sd.exists()) {
//            unzip(dest.getAbsolutePath(), target.getAbsolutePath());
            try {
                unzipFileIntoDirectory(dest,target);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /*public void unzip(String _zipFile, String _targetLocation) {

        //create target location folder if not exist
        _dirChecker(_zipFile);

        try {
            FileInputStream fin = new FileInputStream(_zipFile);
            ZipInputStream zin = new ZipInputStream(fin);
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {

                //create dir if required while unzipping
                if (ze.isDirectory()) {
                    _dirChecker(ze.getName());
                } else {
                    FileOutputStream fout = new FileOutputStream(_targetLocation + ze.getName());
                    for (int c = zin.read(); c != -1; c = zin.read()) {
                        fout.write(c);
                    }

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

            }
            zin.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }*/
    public void unzip() {
        try  {

            ContextWrapper cws=new ContextWrapper(this);
            File sd=cws.getDir("zipper1",MODE_PRIVATE);
            File dest=new File(sd,"parts1");
            dest.mkdirs();
//             final String ROOT_LOCATION = "/sdcard";
            Log.i("", "Starting to unzip");
            InputStream fin = _zipFileStream;
            if(fin == null) {
                fin = new FileInputStream(_zipFile);
            }
            ZipInputStream zin = new ZipInputStream(fin);
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {
                Log.v("", "Unzipping " + ze.getName());

                if(ze.isDirectory()) {
                    _dirChecker(dest + "/" + ze.getName());
                } else {
                    FileOutputStream fout = new FileOutputStream(new File(sd.getPath(), ze.getName()));
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int count;

                    // reading and writing
                    while((count = zin.read(buffer)) != -1)
                    {
                        baos.write(buffer, 0, count);
                        byte[] bytes = baos.toByteArray();
                        fout.write(bytes);
                        baos.reset();
                    }

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

            }
            zin.close();
            Log.i("", "Finished unzip");
        } catch(Exception e) {
            Log.e("", "Unzip Error", e);
        }

    }
    public void unzipFileIntoDirectory(File archive, File destinationDir)
            throws Exception {
        final int BUFFER_SIZE = 1024;
        BufferedOutputStream dest = null;
        FileInputStream fis = new FileInputStream(archive);
        ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
        ZipEntry entry;
        File destFile;
        while ((entry = zis.getNextEntry()) != null) {
            destFile=new File(destinationDir,entry.getName());
            uriToBitmap(Uri.fromFile(destFile),entry.getName());
//            destFile = FilesystemUtils.combineFileNames(destinationDir, entry.getName());
            if (entry.isDirectory()) {
                destFile.mkdirs();
                continue;
            } else {
                int count;
                byte data[] = new byte[BUFFER_SIZE];
                destFile.getParentFile().mkdirs();
                FileOutputStream fos = new FileOutputStream(destFile);
                dest = new BufferedOutputStream(fos, BUFFER_SIZE);
                while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
                    dest.write(data, 0, count);
                }
                dest.flush();
                dest.close();
                fos.close();
            }
        }

        zis.close();
        fis.close();
    }
    private void _dirChecker(String dir) {
        File f = new File(dir);

        if(!f.isDirectory()) {
            f.mkdirs();
        }
    }
    private class ImageDownloader extends AsyncTask {

        @Override
        protected Object doInBackground(Object[] params) {
             String url="testing/dummy.zip";

            return downloadBitmap(url);
        }

        @Override
        protected void onPreExecute() {
            Log.i("Async-Example", "onPreExecute Called");
            simpleWaitDialog = new ProgressDialog(MainActivity.this);
            simpleWaitDialog.setMessage( "Downloading Image");
            simpleWaitDialog.show();


        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            simpleWaitDialog.dismiss();
        }


        private Bitmap downloadBitmap(String url) {
            downloadImage(url);
            return null;
        }

    }
    public void downloadImage(String urlPart) {
        URL url = null;
        FileDescriptor fd;
        try {
            int count;

            url = new URL(urlPart);
            InputStream input = new BufferedInputStream(url.openStream());
            ContextWrapper contextWrapper=new ContextWrapper(this);
            File sd = contextWrapper.getDir("zipper1", MODE_PRIVATE);
            File dest = new File(sd, "theme1.zip");
            _zipFileStream=input;

//           File file = new File(downloadLocation);
            FileOutputStream output = new FileOutputStream(dest); //context.openFileOutput("content.zip", Context.MODE_PRIVATE);
            fd = output.getFD();
            byte data[] = new byte[1024];
            long total = 0;
            while ((count = input.read(data)) != -1) {
                total += count;
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    Toast.makeText(getApplicationContext(),"success",Toast.LENGTH_LONG).show();

                }
            });
            //old code
          /*  ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int n = 0;
            while (-1 != (n = in.read(buf))) {
                out.write(buf, 0, n);
            }
            out.close();
            in.close();
            byte[] response = out.toByteArray();
            String zipString = Base64.encodeToString(response, Base64.DEFAULT);
            ContextWrapper contextWrapper=new ContextWrapper(this);


                File sd = contextWrapper.getDir("zipper1", MODE_PRIVATE);
                File dest = new File(sd, "theme1.zip");
                FileOutputStream fos = new FileOutputStream(dest);
                fos.write(zipString.getBytes());
                fos.close();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    Toast.makeText(getApplicationContext(),"success",Toast.LENGTH_LONG).show();

                }
            });*/
        }
        catch (Exception e) {
            e.printStackTrace();
        }

    }
}