Java NIO学习笔记三------Chanel的四种实现篇
FileChannel
FileChannel是什么
FileChannel是一个连接到文件的通道,可以通过文件通道读写文件。它无法设置为非阻塞模式,总是运行在阻塞模式下。
打开FileChannel
我们可以通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例。例如:
RandomAccessFile aFile = new RandomAccessFile("D:/demo/data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
读FileChannel
调用FileChannel.read()方法,例如:
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
read()方法返回的int值表示了有多少字节被读到了Buffer中。如果返回-1,表示到了文件末尾。
写FileChannel
调用FileChannel.write()方法,例如:
String newData = "Some data";ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();while(buf.hasRemaining()) {channel.write(buf);
}
因为无法保证write()方法一次能向FileChannel写入多少字节,因此需要重复调用write()方法,直到Buffer中已经没有尚未写入通道的字节。
关闭FileChannel
用完FileChannel后必须将其关闭,例如:
channel.close();
FileChannel的位置
调用position()方法可以获取FileChannel的当前位置,调用position(long pos)方法设置FileChannel的当前位置。例如:
long pos = channel.position();
channel.position(pos + 100);
如果将位置设置在文件结束符之后,然后从通道中读数据,读方法将返回-1 ,也就是文件结束标志。
如果将位置设置在文件结束符之后,然后向通道中写数据,文件将撑大到当前位置并写入数据。这可能导致“文件空洞”,磁盘上物理文件中写入的数据间有空隙。
获取文件的大小
long fileSize = channel.size();
截取文件
调用FileChannel.truncate()方法,截取文件时,文件中指定长度后面的部分将被删除。如:
channel.truncate(1024);
强制写入磁盘
操作系统一般会将数据缓存在内存中,写入到FileChannel里的数据不一定会即时写到磁盘上。调用force()方法可以将通道里尚未写入磁盘的数据强制写到磁盘上。
force()方法有一个boolean类型的参数,true表示同时将文件元数据(权限信息等)写到磁盘上,例如:
channel.force(true);
SocketChannel
SocketChannel是什么
SocketChannel是一个连接到TCP网络套接字的通道。
打开 SocketChannel
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://www.xxx.com", 80));
关闭 SocketChannel
socketChannel.close();
读SocketChannel
同读FileChannel。
写SocketChannel
同写FileChannel。
非阻塞模式下的连接
非阻塞模式下调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()方法。
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://www.xxx.com", 80));while(!socketChannel.finishConnect() ){// wait, or do something else
}
非阻塞模式下的读
非阻塞模式下,read()方法在尚未读到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。
非阻塞模式下的写
非阻塞模式下,write()方法在尚未写出任何数据时可能就返回了。所以需要在循环中调用write()。
ServerSocketChannel
ServerSocketChannel是什么
ServerSocketChannel 是一个可以监听新进来的TCP连接的通道,就像标准IO中的ServerSocket一样。
打开 ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
关闭 ServerSocketChannel
serverSocketChannel.close();
监听新进来的连接
用ServerSocketChannel.accept()方法监听新进来的连接。当 accept()方法返回的时候,它返回一个包含新进来的连接的 SocketChannel。因此,accept()方法会一直阻塞到有新连接到达。
while(true){SocketChannel socketChannel = serverSocketChannel.accept();// do something
}
如果是非阻塞模式,accept()方法会立刻返回,如果还没有新进来的连接,返回的将是null。 因此,需要检查返回的SocketChannel是否是null.
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(80));
serverSocketChannel.configureBlocking(false);while(true) {SocketChannel socketChannel = serverSocketChannel.accept();if (socketChannel != null) {//do something}
}
DatagramChannel
DatagramChannel是什么
DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。
打开 DatagramChannel
DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(9000));
接收数据
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
channel.receive(buf);
发送数据
String newData = "Some data";ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();int bytesSent = channel.send(buf, new InetSocketAddress("www.xxx.com", 9000));
连接
由于UDP是无连接的,连接到特定地址并不会像TCP通道那样创建一个真正的连接,而是锁住DatagramChannel ,让其只能从特定地址收发数据。
channel.connect(new InetSocketAddress("www.xxx.com", 9000));
当连接后,也可以使用read()和write()方法,就像在用传统的通道一样,只是在数据传送方面没有任何保证。
Java NIO学习笔记三------Chanel的四种实现篇相关推荐
- Java NIO学习笔记 三 散点/收集 和频道转换
Java NIO散点/收集 Java NIO带有内置的分散/收集支持.散点/收集是读取和写入渠道过程中使用的概念. 从通道散射读取是将数据读入多个缓冲区的读取操作.因此,数据可以从通道"散布 ...
- Java NIO 学习笔记(三)----Selector
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java NIO学习笔记之图解ByteBuffer
转载自 Java NIO学习笔记之图解ByteBuffer ByteBuffer前前后后看过好几次了,实际使用也用了一些,总觉得条理不够清晰. <程序员的思维修炼>一本书讲过,主动学习,要 ...
- 【Java基础学习笔记】- Day11 - 第四章 引用类型用法总结
Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 4.1 class作为成员变量 4.2 interface作为成 ...
- Java NIO学习系列三:Selector
前面的两篇文章中总结了Java NIO中的两大基础组件Buffer和Channel的相关知识点,在NIO中都是通过Channel和Buffer的协作来读写数据的,在这个基础上通过selector来协调 ...
- Java nio 学习笔记 相关知识
http://blog.csdn.net/tsyj810883979/article/details/6876594 一.基本概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. ...
- Java基础学习笔记(三)_Java核心技术(高阶)
本篇文章的学习资源来自Java学习视频教程:Java核心技术(高阶)_华东师范大学_中国大学MOOC(慕课) 本篇文章的学习笔记即是对Java核心技术课程的总结,也是对自己学习的总结 文章目录 Jav ...
- Java NIO学习笔记
印象中,我对于NIO的学习,最早是来源于一次面试,面试官问我:"可不可以讲一下Netty的线程模型?".当然了,这个问题没答上来,于是回去后就开始搜Netty的资料,了解Netty ...
最新文章
- 《算法入门经典大赛——培训指南》第二章考试
- 引入extThree20JSON之后,怎么在工程中使用
- 7-8 连续因子 (20 分)
- Laravel核心解读--Database(四) 模型关联
- JVM 问题排查常用命令
- 2步判断晶体管工作状态
- element form 变 table
- Docker学习--基本docker命令
- idea 开源项目申请地址
- java IO 测试题
- 可视化编辑json数据——json editor
- “Master”围棋对战50胜1和,人工智能身份欲揭?
- Java 打印某年某月的月日历
- 4k hidpi 黑苹果_关于4K,1440P显示屏开启HIdpi的问题
- stm32 常见错误之can线通信
- JAVA初学者:适合小白的Java培训学习路线
- 基于Python实现的合同管理系统设计
- 这款游戏可能是minecraft和迷你世界的共同敌人了吧!
- ssm(spring mvc+mybatis)+netty4开发qiq
- Leetcode 1628. Design an Expression Tree With Evaluate Function [Python]