当前位置: 代码迷 >> Android >> Android 打造自己的个性化应用(五):仿墨迹天气实现续-> 使用Ant实现zip/tar的压缩与解压
  详细解决方案

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

热度:17   发布时间:2016-05-01 14:51:11.0
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:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent">            <LinearLayout        android:orientation="vertical" android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:padding="20dip"        android:layout_centerInParent="true">                <RadioGroup            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:orientation="horizontal">            <RadioButton android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:id="@+id/radioZip"                android:checked="true"                android:text="ZIP"/>                        <RadioButton android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:id="@+id/radioTar"                android:text="TAR"                android:layout_marginLeft="10dip"/>        </RadioGroup>                <Button android:text="压缩" android:id="@+id/button1"            android:layout_width="fill_parent" android:layout_height="wrap_content"            android:paddingLeft="30dip" android:paddingRight="30dip"></Button>        <Button android:text="解压" android:id="@+id/button2"            android:layout_width="fill_parent" android:layout_height="wrap_content"            android:paddingLeft="30dip" android:paddingRight="30dip"            android:layout_marginTop="20dip"></Button>    </LinearLayout>       </RelativeLayout>

AntZipActivity:

public class AntZipActivity extends Activity {	public static final	String	TYPE = "type";	public static final	int		TYPE_ZIP = -1;	public static final	int		TYPE_TAR = 1;		public static final String 	SUFFIX_ZIP = ".zip";	public static final String 	SUFFIX_TAR = ".tar";    /** Called when the activity is first created. */	private Button		btnDoCompress;	private Button		btnDecompress;		private RadioButton	radioZip;	private RadioButton	radioTar;		private boolean isZip = true;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.antzip);        radioZip = (RadioButton)findViewById(R.id.radioZip);        isZip = true;        radioZip.setChecked(true);        radioZip.setOnCheckedChangeListener(new OnCheckedChangeListener() {						@Override			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {				System.out.println("radioZip:"+isChecked);				if(isChecked)				{					isZip = true;				}			}		});        radioTar = (RadioButton)findViewById(R.id.radioTar);        radioTar.setOnCheckedChangeListener(new OnCheckedChangeListener() {						@Override			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {				System.out.println("radioTar:"+isChecked);				if(isChecked)				{					isZip = false;				}			}		});        btnDoCompress = (Button)findViewById(R.id.button1);        btnDoCompress.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				//进入压缩界面 				Intent i = new Intent(AntZipActivity.this,DozipActivity.class);				i.putExtra(TYPE, isZip?TYPE_ZIP:TYPE_TAR);				AntZipActivity.this.startActivity(i);			}		});        btnDecompress = (Button)findViewById(R.id.button2);        btnDecompress.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				//进入解压界面 				Intent i = new Intent(AntZipActivity.this,UnzipActivity.class);				i.putExtra(TYPE, isZip?TYPE_ZIP:TYPE_TAR);				AntZipActivity.this.startActivity(i);			}		});    }}

DozipActivity:

public class DozipActivity extends Activity implements OnClickListener{	private EditText etPath;	private EditText etDest;	private Button	btnDozip;	private TextView	tvTip;		private String  srcPath;	private String  zipDest;		private int 	type;	private String 	suffix;	@Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setTitle("Ant-压缩");        type = getIntent().getIntExtra(AntZipActivity.TYPE, AntZipActivity.TYPE_ZIP);        suffix = type==AntZipActivity.TYPE_ZIP ? AntZipActivity.SUFFIX_ZIP:AntZipActivity.SUFFIX_TAR;        setContentView(R.layout.dozip);        //        etPath = (EditText)findViewById(R.id.editText1);        etDest = (EditText)findViewById(R.id.editText2);        //设置一些默认的函数        etPath.setText("/sdcard/antzip");        etDest.setText("/sdcard/antzip"+suffix);        btnDozip = (Button)findViewById(R.id.button);        tvTip	= (TextView)findViewById(R.id.tv_tip);        btnDozip.setOnClickListener(this);    }	@Override	public void onClick(View v) {		srcPath = etPath.getEditableText().toString();		if(TextUtils.isEmpty(srcPath))		{			Toast.makeText(this, "请指定一个路径", Toast.LENGTH_SHORT).show();			return;		}		File srcFile = new File(srcPath);		if(!srcFile.exists())		{			Toast.makeText(this, "指定的压缩包不存在", Toast.LENGTH_SHORT).show();			return;		}		zipDest = etDest.getEditableText().toString();		if(TextUtils.isEmpty(zipDest))		{			//如果用户没有输入目标文件,则生成一个默认的			zipDest = srcFile.getParent();		}		System.out.println("zip name:"+zipDest);		//如果是以/结尾的,则证明用户输入的是一个目录 ,需要在后面加上文件名		if(zipDest.endsWith(File.separator))		{			zipDest+=srcFile.getName()+suffix;		}		else		{			//如果压缩文件名不是以zip/tar结尾,则加上后缀后			if(!zipDest.endsWith(suffix))			{				zipDest +=suffix;			}		}		//如果用户选择的是zip,则用 zipUtil进行压缩		if(type == AntZipActivity.TYPE_ZIP)		{			ZipUtil zipp = new ZipUtil();			zipp.doZip(srcPath, zipDest);		}		//如果用户选择的是tar,则用 tarUtil进行压缩		else		{			TarUtil tarr = new TarUtil();			tarr.doTar(srcPath, zipDest);		}		//压缩完成后还是提示用户		tvTip.setText("压缩文件路径:"+zipDest);		Toast.makeText(this, "压缩完成", Toast.LENGTH_SHORT).show();	}}

解压缩工具类ZipUtil:

public class ZipUtil {	private ZipFile         zipFile;     private ZipOutputStream zipOut;     //压缩Zip     private  int      		bufSize;    //size of bytes     private byte[]          buf;     public ZipUtil(){    	//要构造函数中去初始化我们的缓冲区        this.bufSize = 1024*4;         this.buf = new byte[this.bufSize];     }      	/**	 * 对传入的目录或者是文件进行压缩	 * @param srcFile  需要 压缩的目录或者文件	 * @param destFile 压缩文件的路径	 */	public void doZip(String srcFile, String destFile) {// zipDirectoryPath:需要压缩的文件夹名		File zipFile = new File(srcFile);		try {			//生成ZipOutputStream,会把压缩的内容全都通过这个输出流输出,最后写到压缩文件中去			this.zipOut = new ZipOutputStream(new BufferedOutputStream(					new FileOutputStream(destFile)));			//设置压缩的注释			zipOut.setComment("comment");			//设置压缩的编码,如果要压缩的路径中有中文,就用下面的编码			zipOut.setEncoding("GBK");			//启用压缩 			zipOut.setMethod(ZipOutputStream.DEFLATED); 			//压缩级别为最强压缩,但时间要花得多一点 			zipOut.setLevel(Deflater.BEST_COMPRESSION); 						handleFile(zipFile, this.zipOut,"");			//处理完成后关闭我们的输出流			this.zipOut.close();		} catch (IOException ioe) {			ioe.printStackTrace();		}	}	/**	 *  由doZip调用,递归完成目录文件读取	 * @param zipFile	 * @param zipOut	 * @param dirName  这个主要是用来记录压缩文件的一个目录层次结构的	 * @throws IOException	 */	private void handleFile(File zipFile, ZipOutputStream zipOut,String dirName) throws IOException {		System.out.println("遍历文件:"+zipFile.getName());		//如果是一个目录,则遍历		if(zipFile.isDirectory())		{			File[] files = zipFile.listFiles();			if (files.length == 0) {// 如果目录为空,则单独创建之.				//只是放入了空目录的名字				this.zipOut.putNextEntry(new ZipEntry(dirName+zipFile.getName()+File.separator));				this.zipOut.closeEntry();			} else {// 如果目录不为空,则进入递归,处理下一级文件				for (File file : files) {					// 进入递归,处理下一级的文件					handleFile(file, zipOut, dirName+zipFile.getName()+File.separator);				}			}		}		//如果是文件,则直接压缩		else		{			FileInputStream fileIn  = new FileInputStream(zipFile);			//放入一个ZipEntry			this.zipOut.putNextEntry(new ZipEntry(dirName+zipFile.getName()));			int length = 0;			//放入压缩文件的流			while ((length = fileIn.read(this.buf)) > 0) {				this.zipOut.write(this.buf, 0, length);			}			//关闭ZipEntry,完成一个文件的压缩			this.zipOut.closeEntry();		}			}	/**	 * 解压指定zip文件	 * @param unZipfile 压缩文件的路径	 * @param destFile   解压到的目录 	 */	public void unZip(String unZipfile, String destFile) {// unZipfileName需要解压的zip文件名		FileOutputStream fileOut;		File file;		InputStream inputStream;		try {			//生成一个zip的文件			this.zipFile = new ZipFile(unZipfile);			//遍历zipFile中所有的实体,并把他们解压出来			for (@SuppressWarnings("unchecked")			Enumeration<ZipEntry> entries = this.zipFile.getEntries(); entries					.hasMoreElements();) {				ZipEntry entry =  entries.nextElement();				//生成他们解压后的一个文件				file = new File(destFile+File.separator+entry.getName());				if (entry.isDirectory()) {					file.mkdirs();				} else {					// 如果指定文件的目录不存在,则创建之.					File parent = file.getParentFile();					if (!parent.exists()) {						parent.mkdirs();					}					//获取出该压缩实体的输入流					inputStream = zipFile.getInputStream(entry);					fileOut = new FileOutputStream(file);					int length = 0;					//将实体写到本地文件中去					while ((length = inputStream.read(this.buf)) > 0) {						fileOut.write(this.buf, 0, length);					}					fileOut.close();					inputStream.close();				}			}			this.zipFile.close();		} catch (IOException ioe) {			ioe.printStackTrace();		}	}}


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


  相关解决方案