json傳輸二進制的方案【轉】


本文轉自:http://wiyi.org/binary-to-string.html

json 是一種很簡潔的協議,但可惜的是,它只能傳遞基本的數型(int,long,string等),但不能傳遞byte類型。如果想要傳輸圖片等二進制文件的話,是沒辦法直接傳輸。

本文提供一種思路給大家參考,讓大家可以在json傳輸二進制文件,如果大家有這個需求又不知怎么實現的話,也許本文能夠幫到你。思想適用於所有語言,本文以java實現,相信大家很容易就能轉化為自己懂得語言。

 

思路

1. 讀取二進制文件到內存

2. 用Gzip壓縮一下。畢竟是在網絡傳輸嘛,當然你也可以不壓縮。

3. 用Base64 把byte[] 轉成字符串

補充:什么是Base64

以下摘自阮一峰博客,Base64的具體編碼方式,大家可以直接進入

Base64是一種編碼方式,它可以將8位的非英語字符轉化為7位的ASCII字符。這樣的初衷,是為了滿足電子郵件中不能直接使用非ASCII碼字符的規定,但是也有其他重要的意義:

a)所有的二進制文件,都可以因此轉化為可打印的文本編碼,使用文本軟件進行編輯;

b)能夠對文本進行簡單的加密。

實現

主要思路就是以上3步,把字符串添加到json字段后發給服務端,然后服務器再用Base64解密–>Gzip解壓,就能得到原始的二進制文件了。是不是很簡單呢?說了不少,下面我們來看看具體的代碼實現。

***注:Java SE是沒辦法直接用Base64的哦,必須要先自己去下載一份。但Android已經集成了Base64,因此大家可以直接在Android使用。

 

[java] view plain copy
  1. /** 
  2.  * @author xing 
  3.  */  
  4. public class TestBase64 {  
  5.     public static void main(String[] args) {  
  6.         byte[] data = compress(loadFile());  
  7.   
  8.         String json = new String(Base64.encodeBase64(data));  
  9.         System.out.println("data length:" + json.length());  
  10.     }  
  11.       
  12.     /** 
  13.      * 加載本地文件,並轉換為byte數組 
  14.      * @return 
  15.      */  
  16.     public static byte[] loadFile() {  
  17.         File file = new File("d:/11.jpg");  
  18.   
  19.         FileInputStream fis = null;  
  20.         ByteArrayOutputStream baos = null;  
  21.         byte[] data = null ;  
  22.   
  23.         try {  
  24.             fis = new FileInputStream(file);  
  25.             baos = new ByteArrayOutputStream((int) file.length());  
  26.   
  27.             byte[] buffer = new byte[1024];  
  28.             int len = -1;  
  29.             while ((len = fis.read(buffer)) != -1) {  
  30.                 baos.write(buffer, 0, len);  
  31.             }  
  32.               
  33.             data = baos.toByteArray() ;  
  34.   
  35.         } catch (IOException e) {  
  36.             e.printStackTrace();  
  37.         } finally {  
  38.             try {  
  39.                 if (fis != null) {  
  40.                     fis.close();  
  41.                     fis = null;  
  42.                 }  
  43.                   
  44.                 baos.close() ;  
  45.             } catch (IOException e) {  
  46.                 e.printStackTrace();  
  47.             }  
  48.         }  
  49.           
  50.         return data ;  
  51.     }  
  52.       
  53.     /** 
  54.      * 對byte[]進行壓縮 
  55.      *  
  56.      * @param 要壓縮的數據 
  57.      * @return 壓縮后的數據 
  58.      */  
  59.     public static byte[] compress(byte[] data) {  
  60.         System.out.println("before:" + data.length);  
  61.           
  62.         GZIPOutputStream gzip = null ;  
  63.         ByteArrayOutputStream baos = null ;  
  64.         byte[] newData = null ;  
  65.           
  66.         try {  
  67.             baos = new ByteArrayOutputStream() ;  
  68.             gzip = new GZIPOutputStream(baos);  
  69.               
  70.             gzip.write(data);  
  71.             gzip.finish();  
  72.             gzip.flush();  
  73.               
  74.             newData = baos.toByteArray() ;  
  75.         } catch (IOException e) {  
  76.             e.printStackTrace();  
  77.         } finally {  
  78.             try {  
  79.                 gzip.close();  
  80.                 baos.close() ;  
  81.             } catch (IOException e) {  
  82.                 e.printStackTrace();  
  83.             }  
  84.         }  
  85.           
  86.         System.out.println("after:" + newData.length);  
  87.         return newData ;  
  88.     }  
  89. }  


最后輸出了一下字符串長度,大家也許覺得經過壓縮也沒降低多少體積嘛。但大家可以試試不用gzip,你會發現經過轉換的字符串比原來大多了。沒辦法,這是由Base64的算法決定的。所以嘛,還是壓縮一下好。

本文所使用的方法比較簡單,大家如果有更好或者覺得有更好的方式,不妨一起探討一下。

最后順便吐槽一下Java,竟然寫了這么多行代碼。要是用Python,估計沒幾行就能搞定了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM