Netty入门之基础篇二

2023-06-28 14:24:57 浏览数 (2)

Buffer的线程安全问题?

Buffer是非线程安全的

Scattering Reads(大致了解即可)

分散读取。简单来讲是就是将文件进行拆分,写入不同的Buffer中。

  • 代码实例
代码语言:javascript复制
public class TestScatteringReads {
    public static void main(String[] args) {
        try {
            FileChannel channel = new RandomAccessFile("word.txt", "r").getChannel();
            ByteBuffer b1 = ByteBuffer.allocate(3);
            ByteBuffer b2 = ByteBuffer.allocate(3);
            ByteBuffer b3 = ByteBuffer.allocate(5);
            channel.read(new ByteBuffer[]{b1,b2,b3});
            b1.flip();
            b2.flip();
            b3.flip();
            debugAll(b1);
            debugAll(b2);
            debugAll(b3);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Gathering Writes

集中写入,简单理解就是将多个buffer的数据组合到一起填充到channel中。减少数据的拷贝。

  • 代码实例
代码语言:javascript复制
public class TestGatheringWrites {
    public static void main(String[] args) {
        ByteBuffer b1 = StandardCharsets.UTF_8.encode("hello");
        ByteBuffer b2 = StandardCharsets.UTF_8.encode("world");
        ByteBuffer b3 = StandardCharsets.UTF_8.encode("你好");
        try (FileChannel channel = new RandomAccessFile("words2.txt","rw").getChannel()) {
            channel.write(new ByteBuffer[]{b1,b2,b3});
        } catch (IOException e) {
        }
    }
}

接下来给大家简单讲解一下什么是黏包、半包现象 假设网络上又多条数据要发送给服务端,数据之间使用了n进行换行,但是由于某种原因导致服务器接收的时候,数据进行了重新组合(这里的组合只是截断的点不一样,而不是字符串的顺序进行了重新排列),假设原始数据有3条:

  • Hello,worldn
  • I'm paidaxingn
  • How are you?n 结果到了服务器端变成了2个ByteBuffer
  • Hello,worldnI'm paidaxingnHo
  • w are you?n

现在你需要将数据进行恢复

  • 代码演示
代码语言:javascript复制
public static void main(String[] args) {
        ByteBuffer source = ByteBuffer.allocate(32);
        source.put("Hello,worldnI'm paidaxingnHo".getBytes());
        split(source);
        source.put("w are you?n".getBytes());
        split(source);

    }

    private static void split(ByteBuffer source) {
        source.flip();
        for (int i = 0; i < source.limit(); i  ) {
            if (source.get(i) == 'n') {
                // 存入新的bytebuffer
                int lenth = i   1 - source.position(); //消息长度
                ByteBuffer target = ByteBuffer.allocate(lenth);
                // 从soure读  向target写
                for (int j = 0; j < lenth; j  ) {
                    byte b = source.get();
                    target.put(b);

                }
                debugAll(target);
            }
        }
        /*这里不能使用clear  compact*会把未写入的向前压缩*/
        source.compact();
    }

以上关于ByteBuffer的相关知识点就这些,接下来给大家讲解FileChannel,

FileChannel
FileChannel的工作模式

FileChannel只能工作在阻塞模式下 不能和selector一起使用

FileChannel的获取方式:

0 人点赞