esayclick java、js与php互相压缩和解压缩

我们知道,网页通过gzip压缩到前端,大大的减少了网络字符串的传送。

gzip那么优秀,那么就用它吧,php和java 8 都刚好都自带这些模块。

java部分

package com.plugin.tegong;

import java.io.*;
import java.util.Base64;
import java.util.zip.*;

public class StrZipUtil {
    /**
     * @param input 需要压缩的字符串
     * @return 压缩后的字符串
     * @throws IOException IO
     */
    public static String deflate(String input) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(out,new Deflater(9, true));
        try {
            deflaterOutputStream.write(input.getBytes("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            deflaterOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Base64.getEncoder().encodeToString(out.toByteArray());
    }
    /**
     * @param input 需要压缩的字符串
     * @return 压缩后的字符串
     * @throws IOException IO
     */
    public static String inflater(String input) throws IOException {
        //ByteArrayOutputStream out = new ByteArrayOutputStream();

        //ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes("UTF-8")); //ISO-8859-1
        ByteArrayInputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(input));
        InflaterInputStream inflaterIn = new InflaterInputStream(in, new Inflater(true));
        BufferedReader reader = new BufferedReader(new InputStreamReader(inflaterIn));
        String res = "", line;
        while ((line = reader.readLine()) != null) {
            res += line;
        }
        //Log.i(TAG, "Response length: " + res.length() + " response: " + res);
        reader.close();
        inflaterIn.close();
        in.close();
        return res;
    }
    /**
     * @param input 需要压缩的字符串
     * @return 压缩后的字符串
     * @throws IOException IO
     */
    public static String compress(String input) throws IOException {
        if (input == null || input.length() == 0) {
            return input;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzipOs = new GZIPOutputStream(out);
        gzipOs.write(input.getBytes());
        gzipOs.close();
        return out.toString("ISO-8859-1"); //ISO-8859-1
    }
    /**
     * @param zippedStr 压缩后的字符串
     * @return 解压缩后的
     * @throws IOException IO
     */
    public static String uncompress(String zippedStr) throws IOException {
        if (zippedStr == null || zippedStr.length() == 0) {
            return zippedStr;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(zippedStr
                .getBytes("ISO-8859-1")); //ISO-8859-1
        GZIPInputStream gzipIs = new GZIPInputStream(in);
        byte[] buffer = new byte[256];
        int n;
        while ((n = gzipIs.read(buffer)) >= 0) {
            out.write(buffer, 0, n);
        }
        // toString()使用平台默认编码,也可以显式的指定如toString("GBK")
        return out.toString();
    }
}

php就更简单了,默认为no_wrap,就几行代码

$postStr = "假设我是一个...测试测试大文本";
$postStr = gzdeflate($postStr,9); //数字9为最高压缩等级
$postStr=base64_encode($postStr); //转base64方便传输
echo "我是压缩:".$postStr."\n";
$postStr=base64_decode($postStr);
//$postStr=substr($postStr, 2, -4); //java如果为wrap时才用
$result = gzinflate($postStr);
echo "我是解压缩:".htmlspecialchars($result)."\n";

最后说说javascript / nodejs 的压缩、解压缩

这里有一个开源

https://github.com/nodeca/pako

示例

引入依赖

https://cdnjs.com/libraries/pako

网页版

https://cdn.bootcss.com/pako/2.0.4/pako.min.js

https://cdn.jsdelivr.net/npm/pako@2.0.4/dist/pako.min.js

https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js

<script src="https://cdn.jsdelivr.net/pako/1.0.5/pako.min.js"></script>
或者
npm install pako
const pako = require('pako');
// Deflate
//
const input = new Uint8Array();
//... fill input data here
const output = pako.deflateRaw(input);

// Inflate (simple wrapper can throw exception on broken stream)
//
const compressed = new Uint8Array();
//... fill data to uncompress here
try {
  const result = pako.inflateRaw(compressed);
  // ... continue processing
} catch (err) {
  console.log(err);
}

其中,deflateRaw和inflateRaw是no_wrap和php匹配。

而,deflate和inflate是wrap, 使用时这点要注意。

解压缩时,在option配置直接导出字符串,见代码:

var data = pako.inflateRaw(binData,{to:"string"});
//代替
//var data = pako.inflateRaw(binData);
//strData   = String.fromCharCode.apply(null, new Uint16Array(data));

具体详见官方文档。

另外还有一个zlib,因时间关系,暂时没测试

https://github.com/imaya/zlib.js

以备使用的笔记。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注