package com.lf.io; import java.nio.IntBuffer; public class IntBufferDemo { public static void main(String[] args) { // 分配新的 int 缓冲区,参数为缓冲区容量 // 新缓冲区的当前位置将为零,其界限(限制位置)将为其容量。它将具有一个底层实现数组,其数组偏移量将为零。 IntBuffer buffer = IntBuffer.allocate(8); for (int i = 0; i < buffer.capacity(); ++i) { int j = 2 * (i + 1); // 将给定整数写入此缓冲区的当前位置,当前位置递增 buffer.put(j); } // 重设此缓冲区,将限制设置为当前位置,然后将当前位置设置为 0 buffer.flip(); // 查看在当前位置和限制位置之间是否有元素 while (buffer.hasRemaining()) { // 读取此缓冲区当前位置的整数,然后当前位置递增 int j = buffer.get(); System.out.print(j + " "); } } }
输出:2 4 6 8 10 12 14 16
package com.lf.io; import java.io.FileInputStream; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class BufferDemo { public static void main(String args[]) throws Exception { //这用用的是文件 IO 处理 FileInputStream fin = new FileInputStream("E://test.txt"); //创建文件的操作管道 FileChannel fc = fin.getChannel(); //分配一个 10 个大小缓冲区,说白了就是分配一个 10 个大小的 byte 数组 ByteBuffer buffer = ByteBuffer.allocate(10); output("初始化", buffer); //先读一下 fc.read(buffer); output("调用 read()", buffer); //准备操作之前,先锁定操作范围 buffer.flip(); output("调用 flip()", buffer); //判断有没有可读数据 while (buffer.remaining() > 0) { byte b = buffer.get(); System.out.print(((char) b)); } output("调用 get()", buffer); //可以理解为解锁 buffer.clear(); output("调用 clear()", buffer); //最后把管道关闭 fin.close(); } //把这个缓冲里面实时状态给答应出来 public static void output(String step, Buffer buffer) { System.out.println(step + " : "); //容量,数组大小 System.out.print("capacity: " + buffer.capacity() + ", "); //当前操作数据所在的位置,也可以叫做游标 System.out.print("position: " + buffer.position() + ", "); //锁定值,flip,数据操作范围索引只能在 position - limit 之间 System.out.println("limit: " + buffer.limit()); System.out.println(); } }
输出:
初始化 : capacity: 10, position: 0, limit: 10 调用 read() : capacity: 10, position: 4, limit: 10 调用 flip() : capacity: 10, position: 0, limit: 4 LFGB调用 get() : capacity: 10, position: 4, limit: 4 调用 clear() : capacity: 10, position: 0, limit: 10 Process finished with exit code 0
/** * 手动分配缓冲区 */ public class BufferWrap { public void myMethod() { // 分配指定大小的缓冲区 ByteBuffer buffer1 = ByteBuffer.allocate(10); // 包装一个现有的数组 byte array[] = new byte[10]; ByteBuffer buffer2 = ByteBuffer.wrap(array); } }
package com.lf.io; import java.nio.ByteBuffer; /*** 缓冲区分片 */ public class BufferSlice { static public void main(String args[]) throws Exception { ByteBuffer buffer = ByteBuffer.allocate(10); // 缓冲区中的数据 0-9 for (int i = 0; i < buffer.capacity(); ++i) { buffer.put((byte) i); } // 创建子缓冲区 buffer.position(3); buffer.limit(7); ByteBuffer slice = buffer.slice(); // 改变子缓冲区的内容 for (int i = 0; i < slice.capacity(); ++i) { byte b = slice.get(i); b *= 10; slice.put(i, b); } buffer.position(0); buffer.limit(buffer.capacity()); while (buffer.remaining() > 0) { System.out.println(buffer.get()); } } }
输出:
0 1 2 30 40 50 60 7 8 9
package com.lf.io; import java.nio.ByteBuffer; public class ReadOnlyBuffer { static public void main(String args[]) throws Exception { ByteBuffer buffer = ByteBuffer.allocate(10); // 缓冲区中的数据 0-9 for (int i = 0; i < buffer.capacity(); ++i) { buffer.put((byte) i); } // 创建只读缓冲区 ByteBuffer readonly = buffer.asReadOnlyBuffer(); // 改变原缓冲区的内容 for (int i = 0; i < buffer.capacity(); ++i) { byte b = buffer.get(i); b *= 10; buffer.put(i, b); } readonly.position(0); readonly.limit(buffer.capacity()); // 只读缓冲区的内容也随之改变 while (readonly.remaining() > 0) { System.out.println(readonly.get()); } } }
package com.lf.io; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class DirectBuffer { static public void main(String args[]) throws Exception { //首先我们从磁盘上读取刚才我们写出的文件内容 String infile = "E://test.txt"; FileInputStream fin = new FileInputStream(infile); FileChannel fcin = fin.getChannel(); //把刚刚读取的内容写入到一个新的文件中 String outfile = String.format("E://testcopy.txt"); FileOutputStream fout = new FileOutputStream(outfile); FileChannel fcout = fout.getChannel(); // 使用 allocateDirect,而不是 allocate ByteBuffer buffer = ByteBuffer.allocateDirect(1024); while (true) { buffer.clear(); int r = fcin.read(buffer); if (r == -1) { break; } buffer.flip(); fcout.write(buffer); } } }
package com.lf.io; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; /** * IO 映射缓冲区 */ public class MappedBuffer { static private final int start = 0; static private final int size = 1024; static public void main(String args[]) throws Exception { RandomAccessFile raf = new RandomAccessFile("E://test.txt", "rw"); FileChannel fc = raf.getChannel(); //把缓冲区跟文件系统进行一个映射关联 // 只要操作缓冲区里面的内容,文件内容也会跟着改变 MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, start, size); mbb.put(0, (byte) 97); mbb.put(1023, (byte) 122); raf.close(); } }
package com.lf.io; import java.io.FileInputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class FileInputDemo { static public void main(String args[]) throws Exception { FileInputStream fin = new FileInputStream("E://test.txt"); // 获取通道 FileChannel fc = fin.getChannel(); // 创建缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); // 读取数据到缓冲区 fc.read(buffer); buffer.flip(); while (buffer.remaining() > 0) { byte b = buffer.get(); System.out.print(((char) b)); } fin.close(); } }
package com.lf.io; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class FileOutputDemo { static private final byte message[] = {83, 111, 109, 101, 32, 98, 121, 116, 101, 115, 46}; static public void main(String args[]) throws Exception { FileOutputStream fout = new FileOutputStream("E://test.txt"); FileChannel fc = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); for (int i = 0; i < message.length; ++i) { buffer.put(message[i]); } buffer.flip(); fc.write(buffer); fout.close(); } }
看看 SelectorProvider.provider()做了什么:
再看看怎么 new PipeImpl()的:
正如这段注释所描述的:
然后通过 serverChannel1.register(selector, SelectionKey.OP_ACCEPT);把 selector 和 channel 绑定在一起,也就是把 new
这个 poll0()会监听 pollWrapper 中的 FD 有没有数据进出,这会造成 IO 阻塞,直到有数据读写事件发生。比如,由于
原文:https://www.cnblogs.com/flgb/p/13081211.html