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使用。
- /**
- * @author xing
- */
- public class TestBase64 {
- public static void main(String[] args) {
- byte[] data = compress(loadFile());
- String json = new String(Base64.encodeBase64(data));
- System.out.println("data length:" + json.length());
- }
- /**
- * 加载本地文件,并转换为byte数组
- * @return
- */
- public static byte[] loadFile() {
- File file = new File("d:/11.jpg");
- FileInputStream fis = null;
- ByteArrayOutputStream baos = null;
- byte[] data = null ;
- try {
- fis = new FileInputStream(file);
- baos = new ByteArrayOutputStream((int) file.length());
- byte[] buffer = new byte[1024];
- int len = -1;
- while ((len = fis.read(buffer)) != -1) {
- baos.write(buffer, 0, len);
- }
- data = baos.toByteArray() ;
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (fis != null) {
- fis.close();
- fis = null;
- }
- baos.close() ;
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return data ;
- }
- /**
- * 对byte[]进行压缩
- *
- * @param 要压缩的数据
- * @return 压缩后的数据
- */
- public static byte[] compress(byte[] data) {
- System.out.println("before:" + data.length);
- GZIPOutputStream gzip = null ;
- ByteArrayOutputStream baos = null ;
- byte[] newData = null ;
- try {
- baos = new ByteArrayOutputStream() ;
- gzip = new GZIPOutputStream(baos);
- gzip.write(data);
- gzip.finish();
- gzip.flush();
- newData = baos.toByteArray() ;
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- gzip.close();
- baos.close() ;
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- System.out.println("after:" + newData.length);
- return newData ;
- }
- }
最后输出了一下字符串长度,大家也许觉得经过压缩也没降低多少体积嘛。但大家可以试试不用gzip,你会发现经过转换的字符串比原来大多了。没办法,这是由Base64的算法决定的。所以嘛,还是压缩一下好。
本文所使用的方法比较简单,大家如果有更好或者觉得有更好的方式,不妨一起探讨一下。
最后顺便吐槽一下Java,竟然写了这么多行代码。要是用Python,估计没几行就能搞定了。
json传输二进制的方案【转】的更多相关文章
- java http post/get 服务端和客户端实现json传输
注:本文来源于<java http post/get 服务端和客户端实现json传输> 最近需要写http post接口所以学习下. 总的还是不难直接上源码! PostHttpClient ...
- 如何提升mysql replication的性能&多线程传输二进制日志
1,最好使用内网或者专线链路传输binlog数据 (千兆网卡.还不够的话,bounding 技术,扩展带宽) 在my.cnf中强制使用内网ip传输数据bind-address=ip2,将二进制保存在独 ...
- C#.NET序列化XML、JSON、二进制微软自带DLL与newtonsoft(json.net)
序列化是将对象转换成另一种格式(XML.json.二进制byte[]) JSON序列化 .NET中有三种常用的JSON序列化的类,分别是: Newtonsoft.Json.JsonConvert类(推 ...
- Linux企业级项目实践之网络爬虫(16)——使用base64传输二进制数据
用http传输二进制的数据时,需要将二进制做一下转化,例如传输的int类型,将int类型之间转为char以后,丢失掉了长度的信息,如数字123456,本来只有4个字节,但是转化成文本的"12 ...
- atitit.无损传输二进制数据串传输网络
atitit.无损传输二进制数据串传输网络 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1 (推荐) 2 4. utf-8 ...
- gSoap传输二进制数据
最近使用gSoap传输二进制数据,遇到问题.gSoap不能一次传输二进制数据.所以使用分包传送. struct xsd_DwgInfo { ];//分包大小 int m_nReadSize;// bo ...
- HTTP传输二进制初探
[转]HTTP传输二进制初探 http://www.51testing.com/?uid-390472-action-viewspace-itemid-233993 [转]HTTP传输二进制初探 上一 ...
- 将场景导出XML或JSON或二进制而且解析还原场景
导出unity场景的全部游戏对象信息,一种是XML一种是JSON. 本篇文章我们把游戏场景中游戏对象的.旋转.缩放.平移与Prefab的名称导出在XML与JSON中.然后解析刚刚导出的XML或JSON ...
- 关于android端的json传输
比较通用的传输方法 import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; impo ...
随机推荐
- ApiPost自动化测试基础之:接口参数依赖的情景处理
在<ApiPost环境变量之第1课>里,我们介绍了什么是ApiPost环境变量,并如何定义.使用它. 环境变量.接口参数依赖的处理是ApiPost自动化测试的基础.本文主要讲解接口参数依赖 ...
- MySql 时间戳存char还是存int?
一次小事故,让我对时间戳存char还是存int有了深刻的印象. 生产环境的sql条件涉及到时间戳字段的大小比较(between and),当时设计的时间戳类型是char(10),结果当数据量达到200 ...
- collectionView代理方法快速设置cell大小上下左右间隔
#define JianGe 25 #define GeShu 4 #define ScreenWidth ([UIScreen mainScreen].bounds.size.width) #def ...
- ARP协议详解之Gratuitous ARP(免费ARP)
ARP协议详解之Gratuitous ARP(免费ARP) Gratuitous ARP(免费ARP) Gratuitous ARP也称为免费ARP,无故ARP.Gratuitous ARP不同于一般 ...
- Top 10 Revit Architecture 2014 books
Revit Architecture, along with ArchiCAD, is most used BIM software in architectural design. Although ...
- react初始化阶段
初始化阶段可以使用的函数:getDefaultProps:只调用一次,实例之间共享引用.只有在组件的第一个实例被初始化的时候,才会调用他,然后react会把这个函数的返回结果保存起来,从第二个实例开始 ...
- Codeforces Round #505 (Div 1 + Div 2) (A~D)
目录 Codeforces 1025 A.Doggo Recoloring B.Weakened Common Divisor C.Plasticine zebra D.Recovering BST( ...
- vs 2010 :类型化数据集DataSet应用
1.启动服务器资源管理器,建立数据库连接 2.在项目中创建数据集 3.为数据集添加表对象 4.为表适配器tableAdapter添加参数化查询 5.修改表适配器的主查询,或添加其他查询 Update: ...
- Linux __attribute__(("hidden"))、default
记录下: Linux下导出so库接口时在下面情况下无法导出(编译时增加了__attribute__(("hidden"))属性). void * __attribute__((&q ...
- 移动前端开发和 Web 前端开发的区别是什么
可以分成两部分理解1.服务器端开发,也叫后台开发,这是唯一的,对应不同的平台,他负责数据的分发与存储,和一些逻辑的处理.逻辑处理的多少由业务的复杂程度决定.服务端相对独立,与平台没啥关系. 2..1中 ...