Buffer的线程安全问题?
Buffer是非线程安全的
Scattering Reads(大致了解即可)
分散读取。简单来讲是就是将文件进行拆分,写入不同的Buffer中。
- 代码实例
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中。减少数据的拷贝。
- 代码实例
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
现在你需要将数据进行恢复
- 代码演示
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的获取方式: