字符串压缩:
之前在做Android客户端开发的时候,需要请求一个字典类型的http请求接口,由于接口json数据过大,达到6M,当时建议后端对接口返回的json数据逻辑进行处理,在服务端将json串压缩,然后在客户端进行解压,最后在将数据显示在客户端。
Java实现字符串压缩API:
压缩算法有多种,我说知道和接触有java I/O自带的zip和gzip两种方式,此次的压缩和解压用到的主要就是GZIPOutputStream和GZIPInputStream类,看一下例子:
字符串压缩代码:
public static String compress(String source) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
GZIPOutputStream gos = new GZIPOutputStream(bos);
gos.write(source.getBytes("ISO-8859-1"));
gos.close();
return bos.toString("ISO-8859-1");
} catch (IOException var3) {
System.out.println(var3.getStackTrace().toString());
return source;
}
}
字符串解压代码:
/****
* @Method compress 字符串解压方法
* @author source 需要传入待解压的字符串
* 返回值 返回解压后的字符串
****/
public static String uncompress(String source) {
if (source != null && source.length() != 0) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteArrayInputStream bis = new ByteArrayInputStream(source.getBytes("ISO-8859-1"));
GZIPInputStream gis = new GZIPInputStream(bis);
byte[] data = new byte[1024];
for(int len = gis.read(data); len != -1; len = gis.read(data)) {
bos.write(data, 0, len);
}
return bos.toString();
} catch (IOException var6) {
System.out.println(var6.getStackTrace().toString());
return source;
}
} else {
return source;
}
}
测试代码:
public static void main(String[] args) {
// 字符串超过一定的长度
String str = "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfdgfdgf"
+ "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
+ "gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggABCdef123中文~!@#$%^&*()_+{fd}"
+ ";/1111111111111111111111111AAAAAAAAAAAJDLFJDLFJDLFJLDFFFFJEIIIIIIIIIIFJJJJJJJJJJJJALLLLLLLLLLLLLLLLLLLLLLdddddddddddddddddfdfdfdfdfdfdd"
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddessdfrdfdfd"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddgfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggf"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "ddddddddddddddddddddddddddddddddddddddddddddggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" +
"LLppppppppppppppppppppppppppppppppppppppppp===========================------------------------------iiiiiiiiiiiiiiiiiiiiiiiggggggggggggg";
//字符串原始长度处理
String originalStr = str;
System.out.println("原始的字符串长度:" + originalStr.length());
//字符串压缩状态处理
String compressStr = compress(originalStr);
System.out.println("压缩的字符串长度:" + compressStr.length());
//字符串解压方法以及测试解压后字符串长度
String uncompress = uncompress(compressStr);
System.out.println("解压后的字符串长度:" + uncompress.length());
//字符串压缩率
float rate = (float)compressStr.length() / uncompress.length();
System.out.println("字符串压缩率:" + rate);
if(originalStr.equals(uncompress)){
System.out.println("解压后的字符串和原始的字符串长度一样");
}
}
控制台打印输出结果:
原始的字符串长度:1474
压缩的字符串长度:136
解压后的字符串长度:1474
字符串压缩率:0.09226594
如图通过调研compress压缩方法将原始字符串压缩,原始字符串的长度为1474个字节,压缩后字符串大小变为136个字节,字符串的压缩率达到91%。
Java代码实现文件压缩与解压:
api说明:
1:添加ZipTools包(主要解决中文路径压缩解压乱码问题)
2:文件压缩需要用到的类 ZipOutputStream(zip文件压缩需要用到的类)
3:ZipEntry 压缩文件的子文件对象,用于保存压缩文件中文件及其文件夹的一个实列
4:ZipFile 压缩文件的实列,用于zip的解压操作
文件压缩相关代码:
/****
*
* @Method createZipStream 创建ZIP输出流实例
* @param filePath 需要压缩的文件以及路径
* @param fileOutPath 生成压缩的文件以及路径
*
****/
public static void createZipStream(String filePath, String fileOutPath) throws IOException{
OutputStream os = new FileOutputStream(fileOutPath);//根据压缩的文件路径创建要输出的文件
CheckedOutputStream cos = new CheckedOutputStream(os, new CRC32());//检查输出流,采用crc算法,保证文件的一致性
ZipOutputStream zos = new ZipOutputStream(cos);//定义zip文件输出流
zos.setEncoding("GBK");//设置编码格式,防止中文乱码
File file = new File(filePath);//需要压缩的文件以及文件夹对象
compressFile(zos,file);
zos.close();
cos.close();
os.close();
System.out.println("压缩文件完成");
}
/****
* @Method compressFile
* @param ZipOutputStream zip文件输出流
* @param File 要压缩的文件对象
****/
public static void compressFile(ZipOutputStream zos, File file) throws IOException{
String fp = file.getPath().substring(3,file.getPath().length());//去掉盘符
if(file.isDirectory()){//如果是文件目录,添加当前文件夹到zip文件流中
zos.putNextEntry(new ZipEntry(fp + File.separator));
for(File f: file.listFiles()){
compressFile(zos, f);
}
}else{//如果是文件目录,添加当前文件到zip文件流中
System.out.println("正在压缩文件:"+file.getPath());
zos.putNextEntry(new ZipEntry(fp));
InputStream is = new FileInputStream(file.getPath());//用字节方式读取文件
BufferedInputStream bis = new BufferedInputStream(is);//创建一个缓存区
byte [] b = new byte[1024];
//将读取的字节写到zip文件流中
while (bis.read(b) != -1) {
zos.write(b);
}
bis.close();
is.close();
}
}
测试函数以及返回示例:
public static void main(String[] args) throws IOException {
createZipStream(filePath,fileOutPath);
// unCompressFile(fileOutPath);
}
打印压缩文件过程:
正在压缩文件:D:\MyDrivers\backup\dgsetup.exe
正在压缩文件:D:\MyDrivers\backup\driverlist.mf
正在压缩文件:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.inf
正在压缩文件:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.PNF
正在压缩文件:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.sys
压缩文件完成
文件解压相关函数:
/***
*
* @Method unCompressFile
* @param filePath 需要解压的文件路径
*
***/
public static void unCompressFile(String filePath) throws IOException{
File file = new File(filePath);
if(!file.exists()){
System.out.println("当前压缩文件不存在");
return;
}
ZipFile zipFile = new ZipFile(file.getPath(),"GBK");
for(Enumeration<ZipEntry> enumeration = zipFile.getEntries();enumeration.hasMoreElements();){//循环获取zip文件压缩实例
ZipEntry zipEntry = enumeration.nextElement();//获取元素
//如果是空文件不解压
if(!zipEntry.getName().equals(File.separator)){
String path = "D:\\" + zipEntry.getName();
System.out.println("文件名:" + path);
int len = path.length();
//创建解压目录
if(path.substring(len - 1, len).equals("\\")){
File createFile = new File(path);
if(!createFile.exists()){
createFile.mkdirs();//如果当前文件不存在,则创建解压目录
}
}else{
//创建解压后的文件
OutputStream os = new FileOutputStream(new File(path));
BufferedOutputStream bos = new BufferedOutputStream(os);//带缓冲的写出流
InputStream is = zipFile.getInputStream(zipEntry);//读取元素
BufferedInputStream bis = new BufferedInputStream(is);
CheckedInputStream cis = new CheckedInputStream(bis, new CRC32());//检查读取流,用CRC算法检查文件是否一致性
byte[] b = new byte[1024];//字节数组,每次读取1024个字节
//循环读取解压文件的值,将zip流写入新文件中
while (cis.read(b) != -1) {
bos.write(b);
}
cis.close();
bis.close();
is.close();
bos.close();
os.close();
}
}else{
System.out.println("目录名:" + zipEntry.getName());
}
}
System.out.println("文件解压结束");
}
测试解压方法:
public static void main(String[] args) throws IOException {
// createZipStream(filePath,fileOutPath);
unCompressFile(fileOutPath);
}
打印解压文件结果:
文件名:D:\MyDrivers\backup\
文件名:D:\MyDrivers\update\
文件名:D:\MyDrivers\backup\dgsetup.exe
文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\
文件名:D:\MyDrivers\software\disapp\
文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.inf
文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\
文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.PNF
文件名:D:\MyDrivers\backup\driverlist.mf
文件名:D:\MyDrivers\
文件名:D:\MyDrivers\backup\Realtek PCIe GBE Family Controller\rt640x64.inf_amd64_98de0ddb0966f29b\rt640x64.sys
文件名:D:\MyDrivers\hotfix\
文件名:D:\MyDrivers\software\
文件解压结束
自己封装的字符串压缩和文件压缩库:
项目目录结构截图如下:
java_zip.jar包是我封装的字符串和文件压缩jar,slf4j-api-1.7.21.jar,slf4j-nop-1.7.2.jar为代码依赖的日志包,ziptools.jar为JavaApi zip防止中文乱码开发的包。
Api演示代码如下:
public static String filePath = "D:/MyDrivers/";
public static String fileOutPath = "D:/MyDrivers.zip";
//在lib文件中有一个Java_zip.jar
public static void main(String[] args) {
// 字符串超过一定的长度
String str = "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggfdgfdgf"
+ "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg"
+ "gggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggABCdef123中文~!@#$%^&*()_+{fd}"
+ ";/1111111111111111111111111AAAAAAAAAAAJDLFJDLFJDLFJLDFFFFJEIIIIIIIIIIFJJJJJJJJJJJJALLLLLLLLLLLLLLLLLLLLLLdddddddddddddddddfdfdfdfdfdfdd"
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddessdfrdfdfd"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddgfgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggf"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
+ "ddddddddddddddddddddddddddddddddddddddddddddggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" +
"LLppppppppppppppppppppppppppppppppppppppppp===========================------------------------------iiiiiiiiiiiiiiiiiiiiiiiggggggggggggg";
System.out.println("字符串初始长度:" + str.length());
String compressstr = GzipUtils.compress(str);
System.out.println("压缩后字符串长度:" + compressstr.length());
String uncompress = GzipUtils.uncompress(compressstr);
System.out.println("解压后字符串长度:" + uncompress.length());
//压缩文件
// ZipUtil.pack(new File(filePath), new File(fileOutPath));
//解压文件
ZipUtil.unpack(new File(fileOutPath), new File(filePath));
项目Demo地址下载:
https://download.youkuaiyun.com/download/zhangmingziliao/10969290