一、读写概念
1.Channel 读写概念 二、FileChannel 文件读写方法
1.写文件2.读文件3.复制文件4.修改文件 三、ServerSocketChannel Buffer 聚集和分散
1.启动一个ServerSocketChannel2.通过Telnet连接:telnet 127.0.0.1 7800 按【CTRL+]】组合键进入发送数据状态
一、读写概念 1.Channel 读写概念在UTF-8编码中: 一个中文字符等于三个字节,一个中文标点符号占三个字节 一个英文字符等于一个字节,一个英文标点占一个字节 一个数字符号等于一个字节
read ---> 从通道读取数据写入 Buffer write ---> 将 Buffer 数据写入通道二、FileChannel 文件读写方法 1.写文件
public static void saveFile() throws IOException { String str = "Hello Moon"; String filePath = "save.txt"; //创建一个输出流->channel FileOutputStream fileOutputStream = new FileOutputStream(filePath); //通过FileOutputStream获取 对应的 FileChannel //这个FileChannel 真实类型是 FileChannelImpl FileChannel fileChannel = fileOutputStream.getChannel(); //创建一个缓冲区Buffer ByteBuffer buffer = ByteBuffer.allocate(1024); //将Str 放入 Buffer buffer.put(str.getBytes(StandardCharsets.UTF_8)); //对ByteBuffer 进行反转 flip buffer.flip(); //将buffer数据写入通道fileChannel fileChannel.write(buffer); //关闭流 fileOutputStream.close(); }2.读文件
public static void readFile() throws IOException { //创建文件输入流 File file = new File("save.txt"); FileInputStream fileInputStream = new FileInputStream(file); //获取FileChannel FileChannel fileChannel = fileInputStream.getChannel(); //创建字节缓冲区 ByteBuffer buffer = ByteBuffer.allocate((int)file.length()); //将通道内数据读到缓冲区 fileChannel.read(buffer); //将buffer转换为string System.out.println(new String(buffer.array())); fileInputStream.close(); }3.复制文件
public static void copyFile() throws IOException { //1.创建一个输出流->channel FileInputStream fileInputStream = new FileInputStream("save.txt"); //2.获取输入流通道 FileChannel readChannel = fileInputStream.getChannel(); //3.创建输出流 FileOutputStream fileOutputStream = new FileOutputStream("copy.txt"); //4.获取输出流通道 FileChannel writeChannel = fileOutputStream.getChannel(); //5.定义 512 字节的缓冲区 ByteBuffer buffer = ByteBuffer.allocate(512); while (-1 != readChannel.read(buffer)){ //切换读写状态并输出 buffer.flip(); writeChannel.write(buffer); //重置buffer 否则position与limit一致时 缓冲区填满无法在增加新数据 buffer.clear(); } fileInputStream.close(); fileOutputStream.close(); }4.修改文件
public static void modifyFile() throws IOException { RandomAccessFile randomAccessFile = new RandomAccessFile("save.txt","rw"); //获取通道 FileChannel fileChannel = randomAccessFile.getChannel(); //定义编辑区域 MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,5); mappedByteBuffer.put(0,(byte)'h'); fileChannel.close(); }三、ServerSocketChannel Buffer 聚集和分散 1.启动一个ServerSocketChannel
package com.example.netty.channel; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Arrays; public class NIOServerSocketChannel { public static void main(String[] args) throws IOException { //使用 ServerSocketChannel 和 SocketChannel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); InetSocketAddress inetSocketAddress = new InetSocketAddress(7800); serverSocketChannel.socket().bind(inetSocketAddress); //创建Buffer数组 ByteBuffer[] byteBuffers = new ByteBuffer[2]; byteBuffers[0] = ByteBuffer.allocate(5); byteBuffers[1] = ByteBuffer.allocate(3); //等待客户端连接(TELNET) SocketChannel socketChannel = serverSocketChannel.accept(); //假定从客户端读取 8 字节 int messageLength = 8; //循环读取 while (true){ long byteRead = 0; while (byteRead < messageLength){ long read = socketChannel.read(byteBuffers); byteRead += read; //打印buffer标志 Arrays.stream(byteBuffers).forEach(buffer->{ System.out.println("position:" + buffer.position() + " limit:" + buffer.limit()); }); } //读写切换 Arrays.stream(byteBuffers).forEach(buffer->{ buffer.flip(); }); //将数据读出显示到客户端 long byteWrite = 0; while (byteWrite < messageLength){ long write = socketChannel.write(byteBuffers); byteWrite += write; } //清空 Arrays.stream(byteBuffers).forEach(buffer->{ buffer.clear(); }); //打印读写情况 System.out.println("byteRead:" + byteRead + " byteWrite:" + byteWrite); } } }2.通过Telnet连接:telnet 127.0.0.1 7800 按【CTRL+]】组合键进入发送数据状态
第一次发送 6 个字节发现,缓冲区数组未写满,相当于阻塞在此处
继续发送两个字节过来
第二次直接发送 8 个字节发现,程序正常下行
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)