java 在 Android 中以编程方式解压缩文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16142311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:02:45  来源:igfitidea点击:

Unzipping files programmatically in Android

javaandroidandroid-emulatorandroid-download-manager

提问by kumar Sudheer

I am downloading a zip folder and saving in specific folder in my Android device. My application is not accessing the folder as it is zipped. I would like to unzip the folder after downloading from server and save in specific folder.

我正在下载一个 zip 文件夹并保存在我的 Android 设备中的特定文件夹中。我的应用程序在压缩时没有访问该文件夹。我想从服务器下载后解压缩文件夹并保存在特定文件夹中。

And my code is here:

我的代码在这里:

public void DownloadDatabase(String DownloadUrl, String fileName) {
    try {
        File root = android.os.Environment.getExternalStorageDirectory();
        File dir = new File(root.getAbsolutePath() + "/timy/databases");
        if(dir.exists() == false){
             dir.mkdirs();  
        }

        URL url = new URL("http://myexample.com/android/timy.zip");
        File file = new File(dir,fileName);

        long startTime = System.currentTimeMillis();
        Log.d("DownloadManager" , "download url:" +url);
        Log.d("DownloadManager" , "download file name:" + fileName);

        URLConnection uconn = url.openConnection();
        uconn.setConnectTimeout(TIMEOUT_SOCKET);

        InputStream is = uconn.getInputStream();

        ZipInputStream zipinstream = new ZipInputStream(new BufferedInputStream(is));
        ZipEntry zipEntry;

        while((zipEntry = zipinstream.getNextEntry()) != null){
            String zipEntryName = zipEntry.getName();
            File file1 = new File(file + zipEntryName);
            if(file1.exists()){

            }else{
                if(zipEntry.isDirectory()){
                    file1.mkdirs();
                }
            }
        }

        BufferedInputStream bufferinstream = new BufferedInputStream(is);

        ByteArrayBuffer baf = new ByteArrayBuffer(5000);
        int current = 0;
        while((current = bufferinstream.read()) != -1){
            baf.append((byte) current);
        }

        FileOutputStream fos = new FileOutputStream( file);
        fos.write(baf.toByteArray());
        fos.flush();
        fos.close();
        Log.d("DownloadManager" , "download ready in" + ((System.currentTimeMillis() - startTime)/1000) + "sec");
    }
    catch(IOException e) {
        Log.d("DownloadManager" , "Error:" + e);
        e.printStackTrace();
    }

}

And my logcat is showing on error. Just folder is creating in my device and no files are downloading with unzipped. Without using inputZipStream method then my zipped folder is downloading and saving in sdcard. When I want to unzip it, it is not happening.

我的 logcat 显示错误。只是在我的设备中创建了文件夹,并且没有下载解压文件。在不使用 inputZipStream 方法的情况下,我的压缩文件夹正在下载并保存在 sdcard 中。当我想解压缩它时,它不会发生。

回答by Roadies

This article is about how to write a utility class for extracting files and directories in a compressed zip archive, using built-in Java API.

本文是关于如何使用内置 Java API 编写一个实用程序类,用于在压缩的 zip 存档中提取文件和目录。

The java.util.zip package provides the following classes for extracting files and directories from a ZIP archive:

java.util.zip 包提供了以下用于从 ZIP 存档中提取文件和目录的类:

ZipInputStream: this is the main class which can be used for reading zip file and extracting files and directories (entries) within the archive. Here are some important usages of this class: -read a zip via its constructor ZipInputStream(FileInputStream) -read entries of files and directories via method getNextEntry() -read binary data of current entry via method read(byte) -close current entry via method closeEntry() -close the zip file via method close()

ZipInputStream:这是主类,可用于读取 zip 文件并提取存档中的文件和目录(条目)。以下是此类的一些重要用法: - 通过其构造函数 ZipInputStream(FileInputStream) 读取 zip - 通过 getNextEntry() 方法读取文件和目录条目 - 通过 read(byte) 方法读取当前条目的二进制数据 - 通过方法 closeEntry() - 通过方法 close() 关闭 zip 文件

ZipEntry: this class represents an entry in the zip file. Each file or directory is represented as a ZipEntry object. Its method getName() returns a String which represents path of the file/directory. The path is in the following form: folder_1/subfolder_1/subfolder_2/…/subfolder_n/file.ext

ZipEntry:此类代表 zip 文件中的一个条目。每个文件或目录都表示为一个 ZipEntry 对象。它的方法 getName() 返回一个表示文件/目录路径的字符串。路径格式如下:folder_1/subfolder_1/subfolder_2/…/subfolder_n/file.ext

Based on the path of a ZipEntry, we re-create directory structure when extracting the zip file.

根据 ZipEntry 的路径,我们在解压 zip 文件时重新创建目录结构。

Below class is used for unzip download zip and extract file and store your desire location.

下面的类用于解压缩下载 zip 并提取文件并存储您想要的位置。

  public class UnzipUtil
  {
     private String zipFile;
     private String location;

  public UnzipUtil(String zipFile, String location)
  {
     this.zipFile = zipFile;
     this.location = location;

     dirChecker("");
  }

  public void unzip()
 {
   try
 {
      FileInputStream fin = new FileInputStream(zipFile);
      ZipInputStream zin = new ZipInputStream(fin);
      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());     

 byte[] buffer = new byte[8192];
 int len;
 while ((len = zin.read(buffer)) != -1)
 {
  fout.write(buffer, 0, len);
 }
 fout.close();

 zin.closeEntry();

}

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

MainActivity.Class:

MainActivity.Class:

       public class MainActivity extends Activity
        {
        private ProgressDialog mProgressDialog;

        String Url="http://hasmukh/hb.zip";
        String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipFolder/";
        String StorezipFileLocation =Environment.getExternalStorageDirectory() +                       "/DownloadedZip"; 
       String DirectoryName=Environment.getExternalStorageDirectory() + "/unzipFolder/files/";

       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

           DownloadZipfile mew = new DownloadZipfile();
            mew.execute(url);

        }

        //-This is method is used for Download Zip file from server and store in Desire location.
        class DownloadZipfile extends AsyncTask<String, String, String>
         {
         String result ="";
          @Override
          protected void onPreExecute()
          {
            super.onPreExecute();
            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setMessage("Downloading...");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mProgressDialog.setCancelable(false);
            mProgressDialog.show();
            }

             @Override
             protected String doInBackground(String... aurl)
             {
              int count;

                    try
          {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());

OutputStream output = new FileOutputStream(StorezipFileLocation);

byte data[] = new byte[1024];
long total = 0;

while ((count = input.read(data)) != -1)
{
 total += count;
 publishProgress(""+(int)((total*100)/lenghtOfFile));
 output.write(data, 0, count);
}
output.close();
input.close();
result = "true";

         } catch (Exception e) {

         result = "false";
         }
        return null;

       }
        protected void onProgressUpdate(String... progress)
        {
        Log.d("ANDRO_ASYNC",progress[0]);
        mProgressDialog.setProgress(Integer.parseInt(progress[0]));
        }

         @Override
         protected void onPostExecute(String unused)
         {
               mProgressDialog.dismiss();
               if(result.equalsIgnoreCase("true"))
         {
          try
             {
                unzip();
                   } catch (IOException e)
                   {
                 // TODO Auto-generated catch block
              e.printStackTrace();
              }
                 }
                     else
                   {

                   }
                       }
               }
          //This is the method for unzip file which is store your location. And unzip folder will                 store as per your desire location.



             public void unzip() throws IOException 
            {
            mProgressDialog = new ProgressDialog(MainActivity.this);
            mProgressDialog.setMessage("Please Wait...");
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.setCancelable(false);
            mProgressDialog.show();
            new UnZipTask().execute(StorezipFileLocation, DirectoryName);
              }


          private class UnZipTask extends AsyncTask<String, Void, Boolean> 
          {
          @SuppressWarnings("rawtypes")
          @Override
          protected Boolean doInBackground(String... params) 
          {
             String filePath = params[0];
             String destinationPath = params[1];

               File archive = new File(filePath);
                try 
                 {
                 ZipFile zipfile = new ZipFile(archive);
                 for (Enumeration e = zipfile.entries(); e.hasMoreElements();) 
                 {
                         ZipEntry entry = (ZipEntry) e.nextElement();
                         unzipEntry(zipfile, entry, destinationPath);
                    }


         UnzipUtil d = new UnzipUtil(StorezipFileLocation, DirectoryName); 
         d.unzip();

            } 
    catch (Exception e) 
         {
           return false;
         }

          return true;
       }

           @Override
           protected void onPostExecute(Boolean result) 
           {
                mProgressDialog.dismiss(); 

             }


            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("", "Extracting: " + entry);
          BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry));
          BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));

       try 
        {

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

             private void createDir(File dir) 
             {
                if (dir.exists()) 
              {
                   return;
                  }
                    if (!dir.mkdirs()) 
                      {
                        throw new RuntimeException("Can not create dir " + dir);
               }
               }}
                 }

            Note: Do not forgot to add below  permission in android Manifest.xml file.

          <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
      <uses-permission android:name="android.permission.INTERNET" />

Read More

阅读更多

回答by Vivek Hirpara

Unzip Function

解压功能

public void unzip(String _zipFile, String _targetLocation) {

    //create target location folder if not exist 
    dirChecker(_targetLocatioan); 

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

Initialization

初始化

ZipManager zipManager = new ZipManager();

zipManager.unzip(inputPath + inputFile, outputPath);

回答by Ankit Dubey

For android, there is a third party library to be used for free.
this library will download your fileitself and extractit automatically wherever you want.
you can check this library here.
ExtractionLib for Android

对于android,有一个免费使用的第三方库。
这个库会自己下载你的文件并在你想要的任何地方自动提取它。
你可以在这里查看这个库。
适用于 Android 的 ExtractionLib