1.引言
最近在做項目中,平台提供一個http服務給其他系統調用,然后我接收到其他系統的json格式的報文后去解析,然后用拿到的數據去調用corba服務,我再把corba的返回值封裝完成json字符串返回給外部系統。遇到一個接口去調用corba服務,然后corba返回的數據經過封裝后字符串的長度達到7M左右,導致http客戶端無法正常的接收完所有的數據。你可能會說這個接口設計的不合理,為什么不增加查詢條件把查詢條件范圍縮小一點?但是,這個不是本節要討論的內容,主要是因為corba服務已經發布用了很久且不在此次項目改造范圍之內,再者這個corba服務已經上線用了N久,輕易的改變可能會導致未知的錯誤。簽於此,我想到可以把json格式的字符串給壓縮,然后客戶端再解壓。(一是字符串的壓縮比例比較的高,二是字符串的壓縮和解壓實現起來也比較簡單)。雖然,最后沒有用到字符串的壓縮和解壓的方式,而是修改客戶端(1.http客戶端進一步精確查詢條件 2.讀取返回數據流采用循環讀取的方式)來解決此問題,我還是把字符串的壓縮和解壓做一下簡單的記錄。
2.關於壓縮與解壓
壓縮算法有多種,我說知道和接觸有java I/O自帶的zip和gzip兩種方式。
本節主要來簡單介紹一下在系統交互之間遇到大容量的字符串數據交互時,采用一端壓縮,另一端再解壓的方式來發送和接收數據。
關於此次的壓縮和解壓用到的主要就是GZIPOutputStream和GZIPInputStream類,此類的相關介紹在JDK中有詳細的介紹,這里就不再累述了
3.代碼如下:
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.util.zip.GZIPInputStream;
- import java.util.zip.GZIPOutputStream;
- /**
- *
- *Module: ZipUtil.java
- *Description: 對字符串的壓縮及解壓
- *Company:
- *Author: pantp
- *Date: May 6, 2012
- */
- public class ZipStrUtil {
- public static void main(String[] args) throws IOException {
- // 字符串超過一定的長度
- String str = "ABCdef123中文~!@#$%^&*()_+{};/1111111111111111111111111AAAAAAAAAAAJDLFJDLFJDLFJLDFFFFJEIIIIIIIIIIFJJJJJJJJJJJJALLLLLLLLLLLLLLLLLLLLLL" +
- "LLppppppppppppppppppppppppppppppppppppppppp===========================------------------------------iiiiiiiiiiiiiiiiiiiiiii";
- System.out.println("\n原始的字符串為------->" + str);
- float len0=str.length();
- System.out.println("原始的字符串長度為------->"+len0);
- String ys = compress(str);
- System.out.println("\n壓縮后的字符串為----->" + ys);
- float len1=ys.length();
- System.out.println("壓縮后的字符串長度為----->" + len1);
- String jy = unCompress(ys);
- System.out.println("\n解壓縮后的字符串為--->" + jy);
- System.out.println("解壓縮后的字符串長度為--->"+jy.length());
- System.out.println("\n壓縮比例為"+len1/len0);
- //判斷
- if(str.equals(jy)){
- System.out.println("先壓縮再解壓以后字符串和原來的是一模一樣的");
- }
- }
- /**
- * 字符串的壓縮
- *
- * @param str
- * 待壓縮的字符串
- * @return 返回壓縮后的字符串
- * @throws IOException
- */
- public static String compress(String str) throws IOException {
- if (null == str || str.length() <= 0) {
- return str;
- }
- // 創建一個新的 byte 數組輸出流
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- // 使用默認緩沖區大小創建新的輸出流
- GZIPOutputStream gzip = new GZIPOutputStream(out);
- // 將 b.length 個字節寫入此輸出流
- gzip.write(str.getBytes());
- gzip.close();
- // 使用指定的 charsetName,通過解碼字節將緩沖區內容轉換為字符串
- return out.toString("ISO-8859-1");
- }
- /**
- * 字符串的解壓
- *
- * @param str
- * 對字符串解壓
- * @return 返回解壓縮后的字符串
- * @throws IOException
- */
- public static String unCompress(String str) throws IOException {
- if (null == str || str.length() <= 0) {
- return str;
- }
- // 創建一個新的 byte 數組輸出流
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- // 創建一個 ByteArrayInputStream,使用 buf 作為其緩沖區數組
- ByteArrayInputStream in = new ByteArrayInputStream(str
- .getBytes("ISO-8859-1"));
- // 使用默認緩沖區大小創建新的輸入流
- GZIPInputStream gzip = new GZIPInputStream(in);
- byte[] buffer = new byte[256];
- int n = 0;
- while ((n = gzip.read(buffer)) >= 0) {// 將未壓縮數據讀入字節數組
- // 將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此 byte數組輸出流
- out.write(buffer, 0, n);
- }
- // 使用指定的 charsetName,通過解碼字節將緩沖區內容轉換為字符串
- return out.toString("GBK");
- }
-
/**
* 根據byte數組,生成文件
*
* @param bfile
* byte數組
* @param filePath
* 存儲路徑
* @param fileName
* 文件名稱
* @return true:保存成功 false:保存失敗
*/
public static boolean getFile(byte[] bfile, String filePath, String fileName) {
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
boolean result = true;
try {
File dir = new File(filePath);
if (!dir.exists() && dir.isDirectory()) {// 判斷文件目錄是否存在
dir.mkdirs();
}
file = new File(filePath + "\\" + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(bfile);
} catch (Exception e) {
result = false;
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}return result;
} - }