Android 使用 7z 压缩字符串(工作总结)

来源:互联网 发布:js窗口加载事件 编辑:程序博客网 时间:2024/06/15 23:02

写在前面

 通过阅读本篇文章,那你可以学(liao)习(jie)在android中如何对数据进行压缩(String->byte[]), 对文件进行压缩和解压缩。阅读本篇文章大约需要五到十分钟,本人菜鸟,希望多多交流。

对数据进行压缩

  1. 到7z 官网下载 最新的 sdk 文件。 传送门: http://www.7-zip.org/sdk.html 。
    这里写图片描述

    1. 将我们需要的代码 cv 到我们项目中。路径:java/ servenZip

    这里写图片描述

    1. 讲代码复制到我们项目中后,自己手写压缩 方法。
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 .

  1. 对与 我们获得到的 byte [] ,我们肯定是持怀疑态度的。接下来我们就需要 通过 大神的项目 来验证我们的办法是否正确了。github:https://github.com/hzy3774/AndroidP7zip (不是本人),该大神通过c 代码,来实现 7z 解压缩。并且作者 很负责 很热心,我在这里 帮他打一个广告…. 手动笑脸 ☻。(大神的项目 c 使用的头文件 会使用到 ndk 版本位14以下的,所以 我最开始用 ndk16编译的时候 出现头文件丢失的情况。笔者运行时间:2017年12月4日 16:28:46)。

  2. 将我们获取的 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);                }            }        }    }}
原创粉丝点击