项目中有个需求要上传用户的很多信息,考虑到接口响应速度后端同学提出了要对数据进行GZIP压缩。
关于iOS端的GZIP压缩,这是我目前在github上找到的star数最多的一个。GZIP github地址。
手动导入的时候,记得在Targets--Build Phases--Link Binary With Libraries中
添加libz.1.2.5.tbd
。
接下来我们来看看GZIP到底能压缩多少。
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
for (int i = 0; i < 9999 ; i++) { // 模拟一万条简单的数据
NSString *key = [NSString stringWithFormat:@"爱新觉罗----%d",i];
[dic setObject:@"8008208820" forKey:key];
}
NSData *contactData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSLog(@"contactData is %ld 字节", (long)contactData.length);
NSData *zipData = [contactData gzippedData];
NSLog(@"zipData is %ld 字节", (long)zipData.length);
打印结果
经过GZIP压缩后,字节大小缩小幅度很大。但是压缩后的data是无法通过- (nullable instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding;
得到string的,该方法得到的string为nil。因为压缩后导致data里的格式发生了变化。
这个时候我们再来看java中对于压缩的数据解压缩的方法。
/**
* 使用zip进行解压缩
* @param compressedStr 压缩后的文本
* @return 解压后的字符串
*/
public static final String unzip(String compressedStr) {
if (compressedStr == null) {
return null;
}
ByteArrayOutputStream out = null;
ByteArrayInputStream in = null;
ZipInputStream zin = null;
String decompressed = null;
try {
byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
out = new ByteArrayOutputStream();
in = new ByteArrayInputStream(compressed);
zin = new ZipInputStream(in);
zin.getNextEntry();
byte[] buffer = new byte[1024];
int offset = -1;
while ((offset = zin.read(buffer)) != -1) {
out.write(buffer, 0, offset);
}
decompressed = out.toString();
} catch (IOException e) {
decompressed = null;
} finally {
if (zin != null) {
try {
zin.close();
} catch (IOException e) {
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
}
}
}
return decompressed;
}
java的代码没法完全看懂,但是可以看到byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
这句。后端接收到我们压缩后的string先是用base64转,也就是我们压缩后要传一个base64的字符串给后端。
那么最后,只要将zipData转成base64的string给后台即可。[zipData base64EncodedStringWithOptions:0];
网友评论