項目中遇到一個場景:須要將一批數據發送到APP端,且實際應用場景中,對數據的長度有必定的限制,因而就須要用到字符串壓縮。
APP端使用Java
,後端使用Golang
,使用gzip
壓縮,同時涉及到了base64
編碼,中文和西歐字符集轉碼。java
後端:git
APP端github
全部示例代碼能夠在這裏找到golang
func compress(s string) string { //使用GBK字符集encode gbk, err := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(s)) if err != nil { logrus.Error(err) return "" } //轉爲ISO8859_1,也就是latin1字符集 latin1, err := charmap.ISO8859_1.NewDecoder().Bytes(gbk) if err != nil { return "" } //使用gzip壓縮 var buf bytes.Buffer zw := gzip.NewWriter(&buf) _, err = zw.Write(latin1) if err != nil { logrus.Fatal(err) } if err := zw.Close(); err != nil { logrus.Fatal(err) } //使用base64編碼 encoded := base64.StdEncoding.EncodeToString(buf.Bytes()) fmt.Println(encoded) return encoded }
private static String uncompress(String s) throws IOException { //base64 decode byte[] byteArray = Base64.getDecoder().decode(s); ByteArrayInputStream bis = new ByteArrayInputStream(byteArray); //gzip解壓 GZIPInputStream gis = new GZIPInputStream(bis); BufferedReader br = new BufferedReader(new InputStreamReader(gis, "UTF-8")); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } br.close(); gis.close(); bis.close(); //使用latin1字符集得到bytes byte[] latin1 = sb.toString().getBytes("ISO_8859_1"); //轉換回GBK return new String(latin1, "GBK"); }
使用base64編碼,主要是由於通過gzip壓縮後數據,直接轉成字符串的話,會有不少不可見字符,這樣在傳輸過程當中,一般會被服務端框架轉義,從而失真。
代碼僅做爲示例使用,實際業務編碼請注意檢查錯誤和異常等。後端