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的算法决定的。所以嘛,还是压缩一下好。