• Android 打造自己的个性化应用(五):仿墨迹天气实现续--> 使用Ant实现zip/tar的压缩与解压


    上一篇中提到对于Zip包的解压和压缩需要借助Ant 实现,我经过参考了其他的资料,整理后并加上了一些自己的看法:

    这里就具体地讲下如何使用Ant进行解压缩及其原因:

     java中实际是提供了对  zip等压缩格式的支持,但是为什么这里会用到ant呢?

     

    原因主要有两个

    1. java提供的类对于包括有中文字符的路径,文件名支持不够好,你用其它第三方软件解压的时候就会存在乱码。而ant.jar就支持文件名或者路径包括中文字符。

    2. ant.jar提供了强大的工具类,更加方便于我们对压缩与解压的操作。

    注意事项:

    1. 首先说明一下,关于皮肤或者类似于皮肤的Zip包,实际上公司可能会根据自己的规定或需求,自定义压缩包文件的结尾,实际上大多还是Zip包的格式. 具体部分的处理大致上是一样的,因此不再复述, 本文给出的例子已经有Zip包和Tar包的解压缩.

    2. 还有要注意的是,此处为提升理解,因此加入zip/tar压缩,解压的界面,实际应用中此部分无需单独的界面展示(解压缩需要一定时间的话,则为加强用户体验,加入提示框与进度条),请自行编写解压缩管理类进行逻辑判断分别处理.

    3. 测试时需要讲要解压缩的包导入sdcard目录下(若为其他目录,请修改代码中路径)

    首先看一下工程目录:

    程序主界面及解压缩的界面:

    接下来是解压缩核心的代码:

    布局文件: antzip.xml:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="fill_parent">  
    5.       
    6.       
    7.     <LinearLayout  
    8.         android:orientation="vertical" android:layout_width="fill_parent"  
    9.         android:layout_height="wrap_content"  
    10.         android:gravity="center"  
    11.         android:padding="20dip"  
    12.         android:layout_centerInParent="true">  
    13.           
    14.         <RadioGroup  
    15.             android:layout_width="wrap_content"  
    16.             android:layout_height="wrap_content"  
    17.             android:orientation="horizontal">  
    18.             <RadioButton android:layout_width="wrap_content"  
    19.                 android:layout_height="wrap_content"  
    20.                 android:id="@+id/radioZip"  
    21.                 android:checked="true"  
    22.                 android:text="ZIP"/>  
    23.               
    24.             <RadioButton android:layout_width="wrap_content"  
    25.                 android:layout_height="wrap_content"  
    26.                 android:id="@+id/radioTar"  
    27.                 android:text="TAR"  
    28.                 android:layout_marginLeft="10dip"/>  
    29.         </RadioGroup>  
    30.           
    31.         <Button android:text="压缩" android:id="@+id/button1"  
    32.             android:layout_width="fill_parent" android:layout_height="wrap_content"  
    33.             android:paddingLeft="30dip" android:paddingRight="30dip"></Button>  
    34.         <Button android:text="解压" android:id="@+id/button2"  
    35.             android:layout_width="fill_parent" android:layout_height="wrap_content"  
    36.             android:paddingLeft="30dip" android:paddingRight="30dip"  
    37.             android:layout_marginTop="20dip"></Button>  
    38.     </LinearLayout>  
    39.       
    40.      
    41. </RelativeLayout>  


    AntZipActivity:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class AntZipActivity extends Activity {  
    2.     public static final String  TYPE = "type";  
    3.     public static final int     TYPE_ZIP = -1;  
    4.     public static final int     TYPE_TAR = 1;  
    5.       
    6.     public static final String  SUFFIX_ZIP = ".zip";  
    7.     public static final String  SUFFIX_TAR = ".tar";  
    8.     /** Called when the activity is first created. */  
    9.     private Button      btnDoCompress;  
    10.     private Button      btnDecompress;  
    11.       
    12.     private RadioButton radioZip;  
    13.     private RadioButton radioTar;  
    14.       
    15.     private boolean isZip = true;  
    16.     @Override  
    17.     public void onCreate(Bundle savedInstanceState) {  
    18.         super.onCreate(savedInstanceState);  
    19.         setContentView(R.layout.antzip);  
    20.         radioZip = (RadioButton)findViewById(R.id.radioZip);  
    21.         isZip = true;  
    22.         radioZip.setChecked(true);  
    23.         radioZip.setOnCheckedChangeListener(new OnCheckedChangeListener() {  
    24.               
    25.             @Override  
    26.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
    27.                 System.out.println("radioZip:"+isChecked);  
    28.                 if(isChecked)  
    29.                 {  
    30.                     isZip = true;  
    31.                 }  
    32.             }  
    33.         });  
    34.         radioTar = (RadioButton)findViewById(R.id.radioTar);  
    35.         radioTar.setOnCheckedChangeListener(new OnCheckedChangeListener() {  
    36.               
    37.             @Override  
    38.             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {  
    39.                 System.out.println("radioTar:"+isChecked);  
    40.                 if(isChecked)  
    41.                 {  
    42.                     isZip = false;  
    43.                 }  
    44.             }  
    45.         });  
    46.         btnDoCompress = (Button)findViewById(R.id.button1);  
    47.         btnDoCompress.setOnClickListener(new OnClickListener() {  
    48.               
    49.             @Override  
    50.             public void onClick(View v) {  
    51.                 //进入压缩界面   
    52.                 Intent i = new Intent(AntZipActivity.this,DozipActivity.class);  
    53.                 i.putExtra(TYPE, isZip?TYPE_ZIP:TYPE_TAR);  
    54.                 AntZipActivity.this.startActivity(i);  
    55.             }  
    56.         });  
    57.         btnDecompress = (Button)findViewById(R.id.button2);  
    58.         btnDecompress.setOnClickListener(new OnClickListener() {  
    59.               
    60.             @Override  
    61.             public void onClick(View v) {  
    62.                 //进入解压界面   
    63.                 Intent i = new Intent(AntZipActivity.this,UnzipActivity.class);  
    64.                 i.putExtra(TYPE, isZip?TYPE_ZIP:TYPE_TAR);  
    65.                 AntZipActivity.this.startActivity(i);  
    66.             }  
    67.         });  
    68.     }  
    69. }  


    DozipActivity:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class DozipActivity extends Activity implements OnClickListener{  
    2.     private EditText etPath;  
    3.     private EditText etDest;  
    4.     private Button  btnDozip;  
    5.     private TextView    tvTip;  
    6.       
    7.     private String  srcPath;  
    8.     private String  zipDest;  
    9.       
    10.     private int     type;  
    11.     private String  suffix;  
    12.     @Override  
    13.     public void onCreate(Bundle savedInstanceState) {  
    14.         super.onCreate(savedInstanceState);  
    15.         setTitle("Ant-压缩");  
    16.         type = getIntent().getIntExtra(AntZipActivity.TYPE, AntZipActivity.TYPE_ZIP);  
    17.         suffix = type==AntZipActivity.TYPE_ZIP ? AntZipActivity.SUFFIX_ZIP:AntZipActivity.SUFFIX_TAR;  
    18.         setContentView(R.layout.dozip);  
    19.         //  
    20.         etPath = (EditText)findViewById(R.id.editText1);  
    21.         etDest = (EditText)findViewById(R.id.editText2);  
    22.         //设置一些默认的函数  
    23.         etPath.setText("/sdcard/antzip");  
    24.         etDest.setText("/sdcard/antzip"+suffix);  
    25.         btnDozip = (Button)findViewById(R.id.button);  
    26.         tvTip   = (TextView)findViewById(R.id.tv_tip);  
    27.         btnDozip.setOnClickListener(this);  
    28.     }  
    29.     @Override  
    30.     public void onClick(View v) {  
    31.         srcPath = etPath.getEditableText().toString();  
    32.         if(TextUtils.isEmpty(srcPath))  
    33.         {  
    34.             Toast.makeText(this, "请指定一个路径", Toast.LENGTH_SHORT).show();  
    35.             return;  
    36.         }  
    37.         File srcFile = new File(srcPath);  
    38.         if(!srcFile.exists())  
    39.         {  
    40.             Toast.makeText(this, "指定的压缩包不存在", Toast.LENGTH_SHORT).show();  
    41.             return;  
    42.         }  
    43.         zipDest = etDest.getEditableText().toString();  
    44.         if(TextUtils.isEmpty(zipDest))  
    45.         {  
    46.             //如果用户没有输入目标文件,则生成一个默认的  
    47.             zipDest = srcFile.getParent();  
    48.         }  
    49.         System.out.println("zip name:"+zipDest);  
    50.         //如果是以/结尾的,则证明用户输入的是一个目录 ,需要在后面加上文件名  
    51.         if(zipDest.endsWith(File.separator))  
    52.         {  
    53.             zipDest+=srcFile.getName()+suffix;  
    54.         }  
    55.         else  
    56.         {  
    57.             //如果压缩文件名不是以zip/tar结尾,则加上后缀后  
    58.             if(!zipDest.endsWith(suffix))  
    59.             {  
    60.                 zipDest +=suffix;  
    61.             }  
    62.         }  
    63.         //如果用户选择的是zip,则用 zipUtil进行压缩  
    64.         if(type == AntZipActivity.TYPE_ZIP)  
    65.         {  
    66.   
    67.             ZipUtil zipp = new ZipUtil();  
    68.             zipp.doZip(srcPath, zipDest);  
    69.         }  
    70.         //如果用户选择的是tar,则用 tarUtil进行压缩  
    71.         else  
    72.         {  
    73.             TarUtil tarr = new TarUtil();  
    74.             tarr.doTar(srcPath, zipDest);  
    75.         }  
    76.         //压缩完成后还是提示用户  
    77.         tvTip.setText("压缩文件路径:"+zipDest);  
    78.         Toast.makeText(this, "压缩完成", Toast.LENGTH_SHORT).show();  
    79.     }  
    80. }  


    解压缩工具类ZipUtil:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
      1. public class ZipUtil {  
      2.     private ZipFile         zipFile;   
      3.     private ZipOutputStream zipOut;     //压缩Zip   
      4.     private  int            bufSize;    //size of bytes   
      5.     private byte[]          buf;   
      6.   
      7.     public ZipUtil(){  
      8.         //要构造函数中去初始化我们的缓冲区  
      9.         this.bufSize = 1024*4;   
      10.         this.buf = new byte[this.bufSize];   
      11.     }   
      12.        
      13.     /** 
      14.      * 对传入的目录或者是文件进行压缩 
      15.      * @param srcFile  需要 压缩的目录或者文件 
      16.      * @param destFile 压缩文件的路径 
      17.      */  
      18.     public void doZip(String srcFile, String destFile) {// zipDirectoryPath:需要压缩的文件夹名  
      19.         File zipFile = new File(srcFile);  
      20.         try {  
      21.             //生成ZipOutputStream,会把压缩的内容全都通过这个输出流输出,最后写到压缩文件中去  
      22.             this.zipOut = new ZipOutputStream(new BufferedOutputStream(  
      23.                     new FileOutputStream(destFile)));  
      24.             //设置压缩的注释  
      25.             zipOut.setComment("comment");  
      26.             //设置压缩的编码,如果要压缩的路径中有中文,就用下面的编码  
      27.             zipOut.setEncoding("GBK");  
      28.             //启用压缩   
      29.             zipOut.setMethod(ZipOutputStream.DEFLATED);   
      30.   
      31.             //压缩级别为最强压缩,但时间要花得多一点   
      32.             zipOut.setLevel(Deflater.BEST_COMPRESSION);   
      33.               
      34.             handleFile(zipFile, this.zipOut,"");  
      35.             //处理完成后关闭我们的输出流  
      36.             this.zipOut.close();  
      37.         } catch (IOException ioe) {  
      38.             ioe.printStackTrace();  
      39.         }  
      40.     }  
      41.   
      42.     /** 
      43.      *  由doZip调用,递归完成目录文件读取 
      44.      * @param zipFile 
      45.      * @param zipOut 
      46.      * @param dirName  这个主要是用来记录压缩文件的一个目录层次结构的 
      47.      * @throws IOException 
      48.      */  
      49.     private void handleFile(File zipFile, ZipOutputStream zipOut,String dirName) throws IOException {  
      50.         System.out.println("遍历文件:"+zipFile.getName());  
      51.         //如果是一个目录,则遍历  
      52.         if(zipFile.isDirectory())  
      53.         {  
      54.             File[] files = zipFile.listFiles();  
      55.   
      56.             if (files.length == 0) {// 如果目录为空,则单独创建之.  
      57.                 //只是放入了空目录的名字  
      58.                 this.zipOut.putNextEntry(new ZipEntry(dirName+zipFile.getName()+File.separator));  
      59.                 this.zipOut.closeEntry();  
      60.             } else {// 如果目录不为空,则进入递归,处理下一级文件  
      61.                 for (File file : files) {  
      62.                     // 进入递归,处理下一级的文件  
      63.                     handleFile(file, zipOut, dirName+zipFile.getName()+File.separator);  
      64.                 }  
      65.             }  
      66.         }  
      67.         //如果是文件,则直接压缩  
      68.         else  
      69.         {  
      70.             FileInputStream fileIn  = new FileInputStream(zipFile);  
      71.             //放入一个ZipEntry  
      72.             this.zipOut.putNextEntry(new ZipEntry(dirName+zipFile.getName()));  
      73.             int length = 0;  
      74.             //放入压缩文件的流  
      75.             while ((length = fileIn.read(this.buf)) > 0) {  
      76.                 this.zipOut.write(this.buf, 0, length);  
      77.             }  
      78.             //关闭ZipEntry,完成一个文件的压缩  
      79.             this.zipOut.closeEntry();  
      80.         }  
      81.           
      82.     }  
      83.   
      84.     /** 
      85.      * 解压指定zip文件 
      86.      * @param unZipfile 压缩文件的路径 
      87.      * @param destFile   解压到的目录  
      88.      */  
      89.     public void unZip(String unZipfile, String destFile) {// unZipfileName需要解压的zip文件名  
      90.         FileOutputStream fileOut;  
      91.         File file;  
      92.         InputStream inputStream;  
      93.   
      94.         try {  
      95.             //生成一个zip的文件  
      96.             this.zipFile = new ZipFile(unZipfile);  
      97.             //遍历zipFile中所有的实体,并把他们解压出来  
      98.             for (@SuppressWarnings("unchecked")  
      99.             Enumeration<ZipEntry> entries = this.zipFile.getEntries(); entries  
      100.                     .hasMoreElements();) {  
      101.                 ZipEntry entry =  entries.nextElement();  
      102.                 //生成他们解压后的一个文件  
      103.                 file = new File(destFile+File.separator+entry.getName());  
      104.   
      105.                 if (entry.isDirectory()) {  
      106.                     file.mkdirs();  
      107.                 } else {  
      108.                     // 如果指定文件的目录不存在,则创建之.  
      109.                     File parent = file.getParentFile();  
      110.                     if (!parent.exists()) {  
      111.                         parent.mkdirs();  
      112.                     }  
      113.                     //获取出该压缩实体的输入流  
      114.                     inputStream = zipFile.getInputStream(entry);  
      115.   
      116.                     fileOut = new FileOutputStream(file);  
      117.                     int length = 0;  
      118.                     //将实体写到本地文件中去  
      119.                     while ((length = inputStream.read(this.buf)) > 0) {  
      120.                         fileOut.write(this.buf, 0, length);  
      121.                     }  
      122.                     fileOut.close();  
      123.                     inputStream.close();  
      124.                 }  
      125.             }  
      126.             this.zipFile.close();  
      127.         } catch (IOException ioe) {  
      128.             ioe.printStackTrace();  
      129.         }  
      130.     }  
      131. }  
  • 相关阅读:
    WebView中实现文件下载功能
    PrograssBar的setIndeterminateDrawable不起作用
    62个Android Studio小技巧合集
    Touch 事件的分发和消费机制
    AndroidStudio
    pagefile.sys and heberfil.sys
    android ANR产生原因和解决办法
    JAVA中分为基本数据类型及引用数据类型
    handler
    洛谷 P2709 小B的询问
  • 原文地址:https://www.cnblogs.com/dongweiq/p/4249935.html
Copyright © 2020-2023  润新知