Jsonバイナリデータ

2929 ワード

jsonは簡潔なプロトコルですが、残念なことに、基本的な数型(int,long,stringなど)しか伝達できませんが、byteタイプは伝達できません.画像などのバイナリファイルを転送したい場合は、直接転送することはできません.本文はみんなに参考を提供して、jsonでバイナリファイルを伝送することができて、もしみんながこの需要があってまたどのように実現するか分からないならば、本文はあなたを助けることができるかもしれません.思想はすべての言語に適用され、本文はjavaで実現され、みんなが簡単に自分の言語を知っていることに転化できると信じています.考え方1.メモリ2にバイナリファイルを読み込む.Gzipで圧縮します.ネットで伝送されているのですから、もちろん圧縮しなくてもいいです.3.Base 64でbyte[]を文字列に変えて補足:Base 64以下はチェン一峰ブログから抜粋し、Base 64の具体的な符号化方式は、直接入ることができます.Base 64は、8ビットの非英語文字を7ビットのASCII文字に変換する符号化方式である.このような目的は,電子メールで非ASCII符号文字を直接使用できないという規定を満たすためであるが,a)すべてのバイナリファイルが印刷可能なテキスト符号化に変換され,テキストソフトウェアを用いて編集されるという他の重要な意義もある.b)テキストを簡単に暗号化できる.実現の主な構想は以上の3つのステップで、文字列をjsonフィールドに追加してサービス側に送り、サーバーがBase 64で解読する-->Gzipで解凍すれば、元のバイナリファイルが得られる.簡単ではないでしょうか.多くのことを言いましたが、具体的なコード実装を見てみましょう.
***注:Java SEはBase 64を直接使うことはできませんよ.まず自分でダウンロードしなければなりません.しかし、AndroidはBase 64を統合しているので、Androidで直接使用することができます.
<span style="font-size:18px;">/**
 * @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 ;
	}
}</span>

最後に文字列の長さを出力しましたが、圧縮してもあまりボリュームが下がっていないと思いますか.しかし、gzipを使わないと、変換された文字列が元よりずっと多いことがわかります.仕方ありません.これはBase 64のアルゴリズムによって決まります.だから、圧縮したほうがいい.
本文で使用する方法は簡単ですが、もっと良い方法やもっと良い方法があれば、一緒に検討してみてはいかがでしょうか.
最後にJavaにツッコミを入れたところ、こんなにたくさんの行のコードが書かれていました.Pythonを使えば、何行もできないだろう.