★ 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