您的位置:首页 > 移动开发 > Android开发

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

2012-09-07 10:03 776 查看
上一篇中提到对于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();
		}
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐