【文件压缩】 Android Jar、Zip文件压缩和解压缩处理


★ java的zip工具包(java.util.zip)

参考代码:

package com.zlf.jarzip;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

	public void onClick_Jar_Compress(View view) {
		try {
			// 使用FileOutputStream对象指定一个要输出的压缩文件(file.jar)
			FileOutputStream fos = new FileOutputStream(
					android.os.Environment.getExternalStorageDirectory()
							+ "/file.jar");
			// 第一步:创建JarOutputStream对象
			JarOutputStream jar = new JarOutputStream(fos);
			// 第二步:创建一个JarEntry对象,并指定待压缩文件在压缩包中的文件名
			JarEntry jarEntry = new JarEntry("jarjar.xml");
			// 第三步:使用putNextEntry方法打开当前的JarEntry对象
			jar.putNextEntry(jarEntry);
			InputStream is = getResources().getAssets().open("strings.xml");
			byte[] buffer = new byte[8192];
			int count = 0;
			// 第四步:写入数据
			while ((count = is.read(buffer)) >= 0) {
				jar.write(buffer, 0, count);
			}
			is.close();
			// 第五步:关闭当前的jarEntry对象
			jar.closeEntry();
			jar.close();
			Toast.makeText(this, "成功将strings.xml文件以jar格式压缩", Toast.LENGTH_SHORT)
					.show();
		} catch (Exception e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
		}
	}

	public void onClick_Jar_Uncompress(View view) {
		try {
			// 定义要解压的文件
			String fileName = android.os.Environment
					.getExternalStorageDirectory() + "/file.jar";
			if (!new File(fileName).exists()) {
				Toast.makeText(this, "压缩文件不存在", Toast.LENGTH_SHORT).show();
				return;
			}
			// 使用FileInputStream对象指定要解压的文件
			FileInputStream fis = new FileInputStream(fileName);
			// 第一步:创建JarInputStream对象来读取压缩文件file.jar
			JarInputStream jis = new JarInputStream(fis);
			// 第二步:调用getNextJarEntry方法打开压缩包中的第一个文件(如果有多个压缩包,可多次调用该方法)
			JarEntry jarEntry = jis.getNextJarEntry();
			// 输出已解压的文件
			FileOutputStream fos = new FileOutputStream(
					android.os.Environment.getExternalStorageDirectory() + "/"
							+ jarEntry.getName());
			byte[] buffer = new byte[8192];
			int count = 0;
			while ((count = jis.read()) >= 0) {
				fos.write(buffer, 0, count);
			}
			jis.closeEntry();
			jis.close();
			fos.close();
			Toast.makeText(this, "成功解压jar格式文件", Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
		}
	}

	public void onClick_Zip_Compress(View view) {
		try {
			// 指定了两个待压缩的文件,都在assets目录中
			
			String[] filenames = new String[] { "activity_main.xml",
					"strings.xml" };
			FileOutputStream fos = new FileOutputStream(
					android.os.Environment.getExternalStorageDirectory()
							+ "/file.zip");
			ZipOutputStream zos = new ZipOutputStream(fos);
			int i = 1;
			// 枚举filenames中的所有待压缩文件
			while (i <= filenames.length) {
				// 从filenames数组中取出当前待压缩的文件名,作为压缩后的名称,以保证压缩前后文件名一致
				ZipEntry zipEntry = new ZipEntry(filenames[i - 1]);
				// 打开当前的zipEntry对象
				zos.putNextEntry(zipEntry);

				InputStream is = getResources().getAssets().open(
						filenames[i - 1]);
				byte[] buffer = new byte[8192];
				int count = 0;
				// 写入数据
				while ((count = is.read(buffer)) >= 0) {
					zos.write(buffer, 0, count);
				}
				zos.flush();
				zos.closeEntry();
				is.close();
				i++;

			}
			zos.finish();
			zos.close();
			Toast.makeText(this, "成功将activity_main.xml、strings.xml文件以zip格式压缩.",
					Toast.LENGTH_LONG).show();

		} catch (Exception e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
		}

	}

	public void onClick_Zip_Uncompress(View view) {
		try {
			// 指定待解压的文件
			String filename = android.os.Environment
					.getExternalStorageDirectory() + "/file.zip";
			if (!new File(filename).exists()) {
				Toast.makeText(this, "压缩文件不存在.", Toast.LENGTH_LONG).show();
				return;
			}
			FileInputStream fis = new FileInputStream(filename);
			ZipInputStream zis = new ZipInputStream(fis);
			ZipEntry zipEntry = null;
			// 通过不断调用getNextEntry方法来解压file.zip中的所有文件
			while ((zipEntry = zis.getNextEntry()) != null) {
				FileOutputStream fos = new FileOutputStream(
						android.os.Environment.getExternalStorageDirectory()
								+ "/" + zipEntry.getName());

				byte[] buffer = new byte[8192];
				int count = 0;
				while ((count = zis.read(buffer)) >= 0) {
					fos.write(buffer, 0, count);
				}
				zis.closeEntry();
				fos.close();
			}
			zis.close();

			Toast.makeText(this, "成功解压jar格式的文件.", Toast.LENGTH_LONG).show();

		} catch (Exception e) {
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
		}
	}

}

需要添加系统权限:

<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


★ Base64 编码

android.util.Base64.encode(byte[] input, int flags)使用问题

flags使用Base64.DEFAULT时,会默认自动添加换行符等符号,使用NO_WRAP可以去掉换行符,故与服务器传输文件时,前后端处理时需保持一致!

1. CRLF 这个参数看起来比较眼熟,它就是Win风格的换行符,意思就是使用CR LF这一对作为一行的结尾而不是Unix风格的LF;
2. 这个参数是默认,使用默认的方法来加密;
3. NO_PADDING 这个参数是略去加密字符串最后的”=”;
4. NO_WRAP 这个参数意思是略去所有的换行符(设置后CRLF就没用了);
5. URL_SAFE 这个参数意思是加密时不使用对URL和文件名有特殊意义的字符来作为加密字符,具体就是以-和_取代+和/。


★ Apache的zip工具包(ant.jar)

使用java的zip包可以进行简单的文件压缩和解压缩处理时,但是遇到包含中文汉字目录或者包含多层子目录的复杂目录结构时,容易出现各种各样的问题。

对于这种情况, 可以使用apache的zip工具包(所在包为ant.jar )代替JDK的zip工具包,因为java类型自带的不支持中文路径,不过两者使用的方式是一样的,只是apache压缩工具多了设置编码方式的接口,其他基本上是一样的。

Apache的ant.jar包下载地址http://download.csdn.net/detail/wenbitianxiafeng/8946477

参考解压缩源码如下:

	/**
	 * 使用Apache工具包解压缩zip文件
	 * @param sourceFilePath 指定的解压缩文件地址
	 * @param targetDirPath  指定的解压缩目录地址
	 * @throws IOException
	 * @throws FileNotFoundException
	 * @throws ZipException
	 */
	public static void uncompressFile(String sourceFilePath, String targetDirPath)
			throws IOException, FileNotFoundException, ZipException{
        BufferedInputStream bis;
        ZipFile zf = new ZipFile(sourceFilePath, "GBK");
        Enumeration e = zf.getEntries();
        while (e.hasMoreElements()){
            org.apache.tools.zip.ZipEntry ze = (org.apache.tools.zip.ZipEntry) e.nextElement();
            String entryName = ze.getName();
            String path = targetDirPath + "/" + entryName;
            if (ze.isDirectory()){
                System.out.println("正在创建解压目录 - " + entryName);
                File decompressDirFile = new File(path);
                if (!decompressDirFile.exists()){
                    decompressDirFile.mkdirs();
                }
            } else{
                System.out.println("正在创建解压文件 - " + entryName);
                String fileDir = path.substring(0, path.lastIndexOf("/"));
                File fileDirFile = new File(fileDir);
                if (!fileDirFile.exists()){
                    fileDirFile.mkdirs();
                }
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetDirPath + "/" + entryName));
                bis = new BufferedInputStream(zf.getInputStream(ze));
                byte[] readContent = new byte[1024];
                int readCount = bis.read(readContent);
                while (readCount != -1){
                    bos.write(readContent, 0, readCount);
                    readCount = bis.read(readContent);
                }
                bos.close();
            }
        }
        zf.close();
    }


★ Android Assets文件写入SD卡

参考代码如下:

	/**
	 * 复制assets目录下指定文件到sd卡中
	 * @param mContext
	 * @param path
	 */
	public static void deepFile(Context mContext, String path) {
        try {
            String str[] = mContext.getAssets().list(path);
            if (str.length > 0) {
                File file = new File(Environment.getExternalStorageDirectory().getPath(), path);
                file.mkdirs();
                for (String string : str) {
                    path = path + "/" + string;
                    deepFile(mContext, path);
                    path = path.substring(0, path.lastIndexOf('/'));
                }
            } else {
                InputStream is = mContext.getAssets().open(path);
                File subFile = new File(Environment.getExternalStorageDirectory().getPath(), path);
                if (!subFile.exists()) {
					subFile.createNewFile();
				}
                FileOutputStream fos = new FileOutputStream(subFile);
                byte[] buffer = new byte[1024];
                while (true) {
                    int len = is.read(buffer);
                    if (len == -1) {
                        break;
                    }
                    fos.write(buffer, 0, len);
                }
                is.close();
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



补充:

基于字节流的形式传输文件:http://www.cnblogs.com/greatverve/archive/2011/12/23/android-upload.html




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值