我们知道,网页通过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
以备使用的笔记。