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

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值