版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27948659/article/details/78711107
写在前面
通过阅读本篇文章,那你可以学(liao)习(jie)在android中如何对数据进行压缩(String->byte[]),
对文件进行压缩和解压缩。阅读本篇文章大约需要五到十分钟,本人菜鸟,希望多多交流。
对数据进行压缩
到7z 官网下载 最新的 sdk 文件。 传送门: http://www.7-zip.org/sdk.html 。
- 将我们需要的代码 cv 到我们项目中。路径:java/ servenZip
- 讲代码复制到我们项目中后,自己手写压缩 方法。
public byte[] lzmaZip(String xml) throws IOException{
BufferedInputStream inStream = new BufferedInputStream(new ByteArrayInputStream(xml.getBytes()));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
boolean eos = true;
Encoder encoder = new Encoder();
encoder.SetEndMarkerMode(eos);
encoder.WriteCoderProperties(bos);
long fileSize = xml.length();
if (eos)
fileSize = -1;
for (int i = 0; i < 8; i++)
bos.write((int)(fileSize >>> (8 * i)) & 0xFF);
encoder.Code(inStream, bos, -1, -1, null);
return bos.toByteArray() ;
}
*: Encoder 为 Compression / LZMA / Encoder .
对与 我们获得到的 byte [] ,我们肯定是持怀疑态度的。接下来我们就需要 通过 大神的项目 来验证我们的办法是否正确了。github:https://github.com/hzy3774/AndroidP7zip (不是本人),该大神通过c 代码,来实现 7z 解压缩。并且作者 很负责 很热心,我在这里 帮他打一个广告…. 手动笑脸 ☻。(大神的项目 c 使用的头文件 会使用到 ndk 版本位14以下的,所以 我最开始用 ndk16编译的时候 出现头文件丢失的情况。笔者运行时间:2017年12月4日 16:28:46)。
将我们获取的 byte [] 通过文件保存的方式保存到本地,并且后缀名 为7z.
try {
byte[] ss = SevenZipUtil.lzmaZip("大吉大利,今晚吃鸡!随着最近几年健身热," +
"鸡胸肉好像已经成了网红。中国人到底有多爱吃鸡肉?中国从什么开始流行吃鸡?" +
"鸡肉又是怎么一步步登上餐桌的? ");
createFileWithByte(ss);
appUtils.logError("7z 压缩后:"+ Arrays.toString(ss));
} catch (IOException e) {
e.printStackTrace();
}
byte [] 保存成文件
/**
* 根据byte数组生成文件
*
* @param bytes
* 生成文件用到的byte数组
*/
private void createFileWithByte(byte[] bytes) {
// TODO Auto-generated method stub
/**
* 创建File对象,其中包含文件所在的目录以及文件的命名
*/
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "ds",
"two.7z");
// 创建FileOutputStream对象
FileOutputStream outputStream = null;
// 创建BufferedOutputStream对象
BufferedOutputStream bufferedOutputStream = null;
try {
// 如果文件存在则删除
if (file.exists()) {
file.delete();
}
// 在文件系统中根据路径创建一个新的空文件
file.createNewFile();
// 获取FileOutputStream对象
outputStream = new FileOutputStream(file);
// 获取BufferedOutputStream对象
bufferedOutputStream = new BufferedOutputStream(outputStream);
// 往文件所在的缓冲输出流中写byte数据
bufferedOutputStream.write(bytes);
// 刷出缓冲输出流,该步很关键,要是不执行flush()方法,那么文件的内容是空的。
bufferedOutputStream.flush();
} catch (Exception e) {
// 打印异常信息
e.printStackTrace();
} finally {
// 关闭创建的流对象
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
保存到手机上 成功之后 ,我们使用 大神的apk ,寻找到该文件夹所在位置,进行解压。然后我们进入文件管理界面,寻找解压后的文件,查看文件内容,经过 验证,该方法 可行。所以在这里 做下 笔记。 也来 填充一下 自己博文 较少的情况。(实力太菜…)
最后加上 本人使用的 工具类 SevenZipUtil:
/**
* 解压 7z文件
* Created by pul on 2017/12/1.
*/
public class SevenZipUtil {
private final String TAG = "SevenZipUtil";
/**
* 将字符串 压缩 转换为 byte 数组
*
* @param xml
* @return
* @throws IOException
*/
public static byte[] lzmaZip(String xml) throws IOException {
BufferedInputStream inStream = new BufferedInputStream(new ByteArrayInputStream(xml.getBytes()));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
boolean eos = true;
Encoder encoder = new Encoder();
encoder.SetEndMarkerMode(eos);
encoder.WriteCoderProperties(bos);
long fileSize = xml.length();
if (eos)
fileSize = -1;
for (int i = 0; i < 8; i++)
bos.write((int) (fileSize >>> (8 * i)) & 0xFF);
encoder.Code(inStream, bos, -1, -1, null);
return bos.toByteArray();
}
/**
* 解压缩 7z文件
*/
public void extractile(String filepath) {
RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null;
try {
randomAccessFile = new RandomAccessFile(filepath, "r");
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
// Getting simple interface of the archive inArchive
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
Log.e(TAG," Hash | Size | Filename");
Log.e(TAG,"----------+------------+---------");
for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
final int[] hash = new int[]{0};
if (!item.isFolder()) {
ExtractOperationResult result;
final long[] sizeArray = new long[1];
result = item.extractSlow(new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {
//Write to file
FileOutputStream fos;
try {
File file = new File(item.getPath());
//error occours below
// file.getParentFile().mkdirs();
fos = new FileOutputStream(file);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
hash[0] ^= Arrays.hashCode(data); // Consume data
sizeArray[0] += data.length;
return data.length; // Return amount of consumed data
}
});
if (result == ExtractOperationResult.OK) {
Log.e(TAG,String.format("%9X | %10s | %s", //
hash[0], sizeArray[0], item.getPath()));
} else {
Log.e(TAG,"Error extracting item: " + result);
}
}
}
} catch (Exception e) {
Log.e(TAG,"Error occurs: " + e);
e.printStackTrace();
System.exit(1);
} finally {
if (inArchive != null) {
try {
inArchive.close();
} catch (SevenZipException e) {
System.err.println("Error closing archive: " + e);
}
}
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (IOException e) {
System.err.println("Error closing file: " + e);
}
}
}
}
}