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

转载于:https://www.cnblogs.com/mazhenyu/p/9228378.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/413874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA社区版(Community)和付费版(UItimate)的区别

比对类型Ultimate(终极版,付费)Community(社区版,免费)语言支持JavaJavaGroovyGroovyKotlinKotlinScala(通过插件)Scala(通过插件)Python 和 Jython(通过插件)Python 和 Jython(通过插件&#x…

从使用传统Web框架到切换到Spring Boot后的总结

1、前言 其实我接触 Spring Boot 的时间并不长,所以还算一个初学者,这篇文章也算是我对 Spring Boot 学习以及使用过程中的复盘,如果文章出现描述错误或表达不清晰的地方,欢迎大家在评论区留言互动。 没想到 Spring Boot 这两年…

前端学习(2859):简单秒杀系统学习之前端界面布局

<html><head><meta charset"utf-8"><link rel"stylesheet" type"text/css" href"miao.min.css" charset"utf-8"><title>秒杀系统</title></head><body><div class"…

Spring Boot 项目瘦身指南,瘦到不可思议!129M->1.3M

之前在 从使用传统Web框架到切换到Spring Boot后的总结 中提到关于 Spring Boot 编译打包&#xff0c;Spring Boot 应用程序不用额外部署到外部容器中&#xff0c;可以直接通过 Maven 命令将项目编译成可执行的 jar 包&#xff0c;然后通过 java -jar 命令启动即可&#xff0c;…

基于Docker搭建RabbitMQ(多图)

1、一点废话&#xff08;可直接跳转至标题2&#xff09; 通常在拉取镜像之前&#xff0c;除了通过命令执行 docker search xxx 之外&#xff0c;我们还可以通过 Docker 镜像仓库查询指定的镜像。 如下是 rabbitmq 镜像的搜索结果&#xff1a; 一般拉取下载数 stars 数相对比…

基于Docker搭建Redis集群(主从集群)

最近陆陆续续有不少园友加我好友咨询 redis 集群搭建的问题&#xff0c;我觉得之前写的这篇 《基于Docker的Redis集群搭建》 文章一定是有问题了&#xff0c;所以我花了几分钟浏览之前的文章总结了下面几个问题&#xff1a; redis 数量太少&#xff0c;只创建了 3 个实例&…

洛达AirPods鉴别检测工具AB153x_UT,支持1562a 1562f

推荐阅读&#xff1a;AB1562_UT软件分辨真假洛达1562A&#xff0c;洛达1562a怎么鉴别&#xff1f; 洛达 1536u 1562a 1562f 1562m 检测工具&#xff0c; 可根据协议检测出实际使用芯片&#xff0c;免拆机检测华强北airpods使用芯片 一、使用方法 蓝牙连接安卓手机后&#x…

AB1562_UT软件分辨真假洛达1562A,洛达1562a怎么鉴别?

一、使用方法 1、下载并安装 AB1562_UT&#xff0c;下载链接 → https://t.1yb.co/kQIC 2、如上图所示&#xff0c;点击顶部的「选择设备」&#xff0c;弹出窗口中选择你的耳机。 3、点击「连接耳机」 4、显示耳机信息 更多测试方法请点击该链接&#xff1a;https://www.cnblo…

[js] callee和caller的区别和作用是什么?

[js] callee和caller的区别和作用是什么&#xff1f; arguments.callee 指的是当前函数 Function.caller 指的是调用当前函数的函数 举个例子&#xff1a;function a() {console.log(arguments.callee);console.log(a.caller); } function b() {a(); } b(); a();控制台输出&a…

niceyoo的2020年终总结-2021年Flag

碎碎念&#xff0c;向本命年说再见&#xff01; 又到了一年一度立 Flag 的时间了&#xff0c;怎么样&#xff0c;去年的 Flag 大家实现的怎么样&#xff1f;还有信心立下 2021 年的 Flag 吗~ 今年我算比较背的&#xff0c;年初的一次小意外&#xff0c;直接在床上躺了2月&…

[js] AudioContext有什么应用场景?

[js] AudioContext有什么应用场景&#xff1f; AudioContext实例有createAnalyzer()&#xff0c;可以实现音频可视化&#xff0c;还有一个gainNode&#xff0c;可以实现输入(MediaStream or HTMLMediaElement)音量的range调整个人简介 我是歌谣&#xff0c;欢迎和大家一起交流…

MacOS中安装Consul(启动及关闭)

PS&#xff1a;非 brew 安装方式。 官网下载链接&#xff1a;https://www.consul.io/downloads.html 懒得去官网下载&#xff0c;或者官网下载速度慢的可以试一下下方蓝奏云链接。 蓝奏云v1.9.0下载&#xff1a;https://niceyoo.lanzous.com/iUBgwjyd6xa 1、解压并放置指定…

[js] 如何按回车自动提交表单

[js] 如何按回车自动提交表单 监听keydown事件并且判断按键代码为13&#xff0c;触发提交表单按钮或执行提交表单方法个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试…

华强北AirPods洛达1562A固件升级教程,带空间音频(艾创力+东莞豪锐)

Hello 大家好&#xff0c;这里是 niceyoo&#xff0c;我是你们的小源。 今天分享的是洛达1562A的固件升级教程。其实一直不想写这篇&#xff0c;主要是怕出现问题&#xff0c;​怎么讲呢&#xff1f;本身刷机这件事是有风险的&#xff0c;就跟手机系统刷机一样&#xff0c;一旦…

[js] 写一个方法获取图片的方向

[js] 写一个方法获取图片的方向 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"description" content""><m…