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

来源:互联网 发布:知乎 复活 编辑:程序博客网 时间:2024/05/23 00:05

上一篇中提到对于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
  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
  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
  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
  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. }  


完整代码稍后上传....