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使用。




1. /**
2.  * @author xing
3.  */  
4. public class TestBase64 {  
5. public static void main(String[] args) {  
6. byte[] data = compress(loadFile());  
7.   
8. new String(Base64.encodeBase64(data));  
9. "data length:" + json.length());  
10.     }  
11.       
12. /**
13.      * 加载本地文件,并转换为byte数组
14.      * @return
15.      */  
16. public static byte[] loadFile() {  
17. new File("d:/11.jpg");  
18.   
19. null;  
20. null;  
21. byte[] data = null ;  
22.   
23. try {  
24. new FileInputStream(file);  
25. new ByteArrayOutputStream((int) file.length());  
26.   
27. byte[] buffer = new byte[1024];  
28. int len = -1;  
29. while ((len = fis.read(buffer)) != -1) {  
30. 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. 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. "before:" + data.length);  
61.           
62. null ;  
63. null ;  
64. byte[] newData = null ;  
65.           
66. try {  
67. new ByteArrayOutputStream() ;  
68. 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. "after:" + newData.length);  
87. return newData ;  
88.     }  
89. }




最后输出了一下字符串长度,大家也许觉得经过压缩也没降低多少体积嘛。但大家可以试试不用gzip,你会发现经过转换的字符串比原来大多了。没办法,这是由Base64的算法决定的。所以嘛,还是压缩一下好。