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

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

我的代码在这里:

public void DownloadDatabase(String DownloadUrl, String fileName) {尝试 {文件根 = android.os.Environment.getExternalStorageDirectory();文件目录=新文件(root.getAbsolutePath()+/timy/databases");if(dir.exists() == false){dir.mkdirs();}URL url = 新 URL("http://myexample.com/android/timy.zip");文件文件 = 新文件(目录,文件名);long startTime = System.currentTimeMillis();Log.d("DownloadManager" , "下载地址:" +url);Log.d("DownloadManager" , "下载文件名:" + fileName);URLConnection uconn = url.openConnection();uconn.setConnectTimeout(TIMEOUT_SOCKET);InputStream = uconn.getInputStream();ZipInputStream zipinstream = new ZipInputStream(new BufferedInputStream(is));ZipEntry zipEntry;而((zipEntry = zipinstream.getNextEntry()) != null){字符串 zipEntryName = zipEntry.getName();文件 file1 = 新文件(文件 + zipEntryName);如果(file1.exists()){}别的{if(zipEntry.isDirectory()){file1.mkdirs();}}}BufferedInputStream bufferinstream = new BufferedInputStream(is);ByteArrayBuffer baf = new ByteArrayBuffer(5000);整数电流 = 0;而((当前= bufferinstream.read())!= -1){baf.append((字节)当前);}FileOutputStream fos = new FileOutputStream(file);fos.write(baf.toByteArray());fos.flush();fos.close();Log.d("DownloadManager" , "下载就绪" + ((System.currentTimeMillis() - startTime)/1000) + "sec");}捕捉(IOException e){Log.d("DownloadManager" , "错误:" + e);e.printStackTrace();}}

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

解决方案

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

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

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

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

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

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

 公共类 UnzipUtil{私有字符串压缩文件;私有字符串位置;公共 UnzipUtil(字符串 zipFile,字符串位置){这个.zipFile = zipFile;this.location = 位置;dirChecker("");}公共无效解压缩(){尝试{FileInputStream fin = new FileInputStream(zipFile);ZipInputStream zin = new ZipInputStream(fin);ZipEntry ze = null;而 ((ze = zin.getNextEntry()) != null){Log.v("解压", "解压" + ze.getName());如果(ze.isDirectory()){dirChecker(ze.getName());}别的{FileOutputStream fout = new FileOutputStream(location + ze.getName());字节[]缓冲区=新字节[8192];国际化;而 ((len = zin.read(buffer)) != -1){fout.write(buffer, 0, len);}fout.close();zin.closeEntry();}}zin.close();}捕获(异常 e){Log.e("解压", "解压", e);}}私人无效 dirChecker(字符串目录){文件 f = 新文件(位置 + 目录);if(!f.isDirectory()){f.mkdirs();}}}

<块引用>

MainActivity.Class:

 公共类 MainActivity 扩展 Activity{私有 ProgressDialog mProgressDialog;String Url="http://hasmukh/hb.zip";字符串 unzipLocation = Environment.getExternalStorageDirectory() + "/unzipFolder/";String StorezipFileLocation =Environment.getExternalStorageDirectory() + "/DownloadedZip";String DirectoryName=Environment.getExternalStorageDirectory() + "/unzipFolder/files/";@覆盖protected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);设置内容视图(R.layout.main);DownloadZipfile mew = new DownloadZipfile();mew.execute(url);}//-此方法用于从服务器下载 Zip 文件并存储在 Desire 位置.类 DownloadZipfile 扩展 AsyncTask<String, String, String>{字符串结果="";@覆盖受保护的无效 onPreExecute(){super.onPreExecute();mProgressDialog = new ProgressDialog(MainActivity.this);mProgressDialog.setMessage("正在下载...");mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);mProgressDialog.setCancelable(false);mProgressDialog.show();}@覆盖受保护的字符串doInBackground(字符串... aurl){整数计数;尝试{URL url = 新 URL(aurl[0]);URLConnection conexion = url.openConnection();conexion.connect();int lenghtOfFile = conexion.getContentLength();InputStream 输入 = new BufferedInputStream(url.openStream());OutputStream 输出 = new FileOutputStream(StorezipFileLocation);字节数据[] = 新字节[1024];长总计 = 0;while ((count = input.read(data)) != -1){总计 += 计数;publishProgress(""+(int)((total*100)/lenghtOfFile));output.write(数据,0,计数);}输出.close();输入.close();结果=真";} 捕捉(异常 e){结果=假";}返回空值;}受保护的无效onProgressUpdate(字符串...进度){Log.d("ANDRO_ASYNC",progress[0]);mProgressDialog.setProgress(Integer.parseInt(progress[0]));}@覆盖protected void onPostExecute(未使用的字符串){mProgressDialog.dismiss();如果(结果.equalsIgnoreCase(真")){尝试{解压缩();} 捕捉(IOException e){//TODO 自动生成的 catch 块e.printStackTrace();}}别的{}}}//这是解压缩文件的方法,该文件存储您的位置.解压缩文件夹将根据您想要的位置进行存储.public void unzip() 抛出 IOException{mProgressDialog = new ProgressDialog(MainActivity.this);mProgressDialog.setMessage("请稍候...");mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);mProgressDialog.setCancelable(false);mProgressDialog.show();新的 UnZipTask().execute(StorezipFileLocation, DirectoryName);}私有类 UnZipTask 扩展 AsyncTask<String, Void, Boolean>{@SuppressWarnings("rawtypes")@覆盖受保护的布尔doInBackground(字符串...参数){字符串文件路径 = 参数 [0];字符串destinationPath = params[1];文件存档 = 新文件(文件路径);尝试{ZipFile zipfile = new ZipFile(存档);for (枚举 e = zipfile.entries(); e.hasMoreElements();){ZipEntry 条目 = (ZipEntry) e.nextElement();unzipEntry(zipfile, entry, destinationPath);}UnzipUtil d = new UnzipUtil(StorezipFileLocation, DirectoryName);d.unzip();}捕获(异常 e){返回假;}返回真;}@覆盖protected void onPostExecute(布尔结果){mProgressDialog.dismiss();}private void unzipEntry(ZipFile zipfile, ZipEntry entry,String outputDir) 抛出 IOException{if (entry.isDirectory()){createDir(new File(outputDir, entry.getName()));返回;}文件 outputFile = new File(outputDir, entry.getName());if (!outputFile.getParentFile().exists()){createDir(outputFile.getParentFile());}//Log.v("", "正在提取:" + entry);BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry));BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));尝试{}最后{outputStream.flush();outputStream.close();inputStream.close();}}私人无效createDir(文件目录){如果 (dir.exists()){返回;}如果(!dir.mkdirs()){throw new RuntimeException("无法创建目录" + dir);}}}}注意:不要忘记在 android Manifest.xml 文件中添加以下权限.<使用权限 android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></使用权限><使用权限 android:name="android.permission.INTERNET"/>

阅读更多

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.

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.

解决方案

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.

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

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

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

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

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

  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:

       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

相关文章