Nio Buffer Training

作者: 这是一个随便起的昵称 | 来源:发表于2018-07-08 14:59 被阅读11次

上一篇 学习了,ByteBuffer 的一些重要的 Api,这篇借着所学习的知识完成一个小小的Demon

一般我们的数据传输都是明文传输,采用各种各样的格式,如 JSON,XML等。现在就用上篇所学的 Api 来完成一个定制的字节流数据传输格式。即把我们所需要传输的数据以特定的格式(有一定的加密效果)生成,再以特定的格式解析。需要注意的是这个Demon有很大的改进空间。目前只支持以固定顺序读取数据,可以继续改进,读取任意一个数据(重新定义数据格式)。

先来介绍一下基本思路。

  1. 制定特定的数据格式
    | type | length | content |
    type 单个数据的格式(见代码)
    length 数据的长度或 array类型的length。基本数据类型没有长度这个字段。
    content 即内容(byte 字节流)
  2. 以特定的顺序写入数据
    writeInt()
    writeIntArray()
    writeDouble()
    ...
  3. 以特定的顺序读取数据
package com.zsy.nio;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class NIOTraining {

    public static void main(String[] args) throws UnsupportedEncodingException, IOException {
        TransData transData = new TransData();
        byte[] bytes = transData
                .writeInt(165)
                .writeDouble(165.2)
                .writeString("hello world!")
                .writeIntArray(new int[] {85,89,56})
                .writeStringArray(new String[] {"zhongguo","nanjing","Java"})
                .getData();
    

        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);

        while (byteBuffer.hasRemaining()) {
            switch (byteBuffer.get()) {
                case TransData.TYPE_INT:
                    System.out.println(byteBuffer.getInt());
                    break;
                case TransData.TYPE_DOUBLE:
                    System.out.println(byteBuffer.getDouble());
                    break;
                case TransData.TYPE_STRING:
                    int length = byteBuffer.getInt();
                    System.out.println(new String(byteBuffer.array(),byteBuffer.position(), length, "UTF-8"));
                    byteBuffer.position(byteBuffer.position() + length);
                    break;
                case TransData.TYPE_ARRAY_INT:
                    int len = byteBuffer.getInt();
                    int[] results = new int[len];
                    for(int i=0; i<len; i++) {
                        results[i] = byteBuffer.getInt();
                    }
                    System.out.println(Arrays.toString(results));
                    break;
                case TransData.TYPE_ARRAY_STRING:
                    int stringsLength = byteBuffer.getInt();
                    String[] strings = new String[stringsLength];
                    for(int i=0; i<stringsLength; i++) {
                        int stringLen = byteBuffer.getInt();
                        strings[i] = new String(byteBuffer.array(), byteBuffer.position(), stringLen, "UTF-8");
                        byteBuffer.position(byteBuffer.position() + stringLen);
                    }
                    System.out.println(Arrays.toString(strings));
                    break;
            }
        }

    }

    /**
     * |type|length|content| type 1 byte length 4 byte 基本类型不需要 length
     * 
     * @author zhaoxiaosi
     *
     */
    static class TransData {

        private static final byte TYPE_INT = 1;
        private static final byte TYPE_DOUBLE = 2;
        private static final byte TYPE_STRING = 3;

        private static final byte TYPE_ARRAY_STRING = 4;
        private static final byte TYPE_ARRAY_INT = 5;
        private static final byte TYPE_ARRAY_DOUBLE = 6;

        private ByteArrayOutputStream out = new ByteArrayOutputStream();

        public TransData writeInt(int content) {
            out.write(TYPE_INT);
            out.write(content >>> 24);
            out.write(content >>> 16);
            out.write(content >>> 8);
            out.write(content);
            return this;
        }
        
        public TransData writeIntArray(int[] ints) {
            out.write(TYPE_ARRAY_INT);
            writeLength(ints.length);
            for(int i: ints) {
                out.write(i >>> 24);
                out.write(i >>> 16);
                out.write(i >>> 8);
                out.write(i);
            }
            return this;
        }
        
        public TransData writeStringArray(String[] strings) throws IOException {
            out.write(TYPE_ARRAY_STRING);
            writeLength(strings.length);
            for(String string: strings) {
                byte[] bytes = string.getBytes("UTF-8");
                writeLength(bytes.length);
                out.write(bytes);
            }
            return this;
        }

        public TransData writeDouble(double content) {
            long value = Double.doubleToRawLongBits(content);
            out.write(TYPE_DOUBLE);
            out.write((byte) (int)value >>> 56);
            out.write((byte) (int)value >>> 48);
            out.write((byte) (int)value >>> 40);
            out.write((byte) (int)value >>> 32);
            out.write((byte) (int)value >>> 24);
            out.write((byte) (int)value >>> 16);
            out.write((byte) (int)value >>> 8);
            out.write((byte) (int)value);
            return this;
        }
        

        public TransData writeString(String content) throws UnsupportedEncodingException, IOException {
            out.write(TYPE_STRING);
            byte[] bytes = content.getBytes("UTF-8");
            writeLength(bytes.length);
            out.write(bytes);
            return this;
        }
        
        private void writeLength(int length) {
            out.write(length >>> 24);
            out.write(length >>> 16);
            out.write(length >>> 8);
            out.write(length);
        }

        public byte[] getData() {
            return out.toByteArray();
        }

    }
}

output

165
2.16443570729E-312
hello world!
[85, 89, 56]
[zhongguo, nanjing, Java]

相关文章

  • Nio Buffer Training

    上一篇 学习了,ByteBuffer 的一些重要的 Api,这篇借着所学习的知识完成一个小小的Demon 一般我们...

  • java NIO---Buffer

    NIO中Buffer简介 java的NIO中buffer至关重要,buffer是读写的中介,主要和NIO的chan...

  • Buffer

    Java NIO Buffer当我们需要与NIO Channel进行交互时,我们就需要使用到NIO Buffer,...

  • NIO之三--Buffer

    Java NIO Buffer Basic Buffer Usage Buffer Capacity, Posit...

  • Java NIO Buffer

    Java NIO Buffer Buffer使用场景 Java NIO buffers 用于和Java chann...

  • NIO java编程

    NIO 同步式非阻塞式IO NIO组件:Buffer channel selector Buffer 缓冲区 1....

  • NIO(二、Buffer)

    目录 NIO(一、概述)NIO(二、Buffer)NIO(三、Channel)NIO(四、Selector) Bu...

  • NIO(四、Selector)

    目录 NIO(一、概述)NIO(二、Buffer)NIO(三、Channel)NIO(四、Selector) Se...

  • NIO(三、Channel)

    目录 NIO(一、概述)NIO(二、Buffer)NIO(三、Channel)NIO(四、Selector) Ch...

  • Netty之NIO

    ------NIO简介(1)-------- NIO组件 channel,buffer,selector,pip,...

网友评论

    本文标题:Nio Buffer Training

    本文链接:https://www.haomeiwen.com/subject/zzjouftx.html