zoukankan      html  css  js  c++  java
  • 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使用。

     

    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,估计没几行就能搞定了。

  • 相关阅读:
    SurvivalShooter学习笔记(二.玩家移动旋转)
    SurvivalShooter学习笔记(一.相机跟随)
    Unity平台的预处理
    设计模式之简单工厂模式
    求每一位数和
    10进制转化为m进制
    m进制转化为10进制
    【硬件模块】华为NBIOT 使用记录
    【编程语言】Matlab 学习记录
    【设计模式】观察者模式
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/9228378.html
Copyright © 2011-2022 走看看