前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NIO之Channel通道(一)-Channel、FileChannel

NIO之Channel通道(一)-Channel、FileChannel

作者头像
云飞扬
发布2022-04-25 14:20:24
5300
发布2022-04-25 14:20:24
举报
文章被收录于专栏:星汉技术

NIO之Channel通道(一)-Channel、FileChannel

Channel叫做通道,用于I/O操作的连接。与Stream不同,可以双向的进行数据通信。

Channel相关的的类和接口都存放于以下两个包中:

  • java.nio.channels:定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的选择器。
  • java.nio.channels.spi:用于 java.nio.channels 包的服务提供程序类。

1 获取通道的方式

获取通道有以下6种方式。

1.1 getChannel()

Java针对支持通道的类提供了getChannel()方法:

  • 本地IO:FileInputstream、FileOutputstream、RandomAccessFile。
  • 网络IO:Socket、ServerSocket、DatagramSockte。

1.2 open()

在JDK1.7中的NIO.2针对各个通道提供了静态方法open()

1.3 newByteChannel()

在JKD1.7中的NIO.2的Files工具类的newByteChannel()

1.4 数据传输

通道之间的数据传输:

  • transferFrom()
  • transferTo()

1.5 分散与聚集

分散(Scatter)与聚集(Gather):

  • 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区。
  • 聚集写入(Gathering Writes):将多个缓冲区的数据聚集到通道中。

1.6 字符集

字符集:Charset

  • 编码:字符串→字符数组
  • 解码:字符数组→字符串

2 Channel

Channel是一个接口,以下为其实现类和子类继承结构。

代码语言:javascript
复制
Channel
	|-AbstractInterruptibleChannel
	|	|- FileChannel
	|	|- FileChannelImpl
	|- ReadableByteChannelImpl
	|	|- SelectableChannel
	|		|- AbstractSelectableChannel
	|				|- ServerSocketChannel
	|				|- SocketChannel
	|				|- DatagramChannel

2.1 重要方法

此接口只有两个方法,分别如下:

2.1.1 close()

关闭此通道。

2.1.2 isOpen()

判断此通道是否处于打开状态。

3 FileChannel

主要用于文件的读写,可以从磁盘上读取文件,也可以向磁盘上写入文件。

这是一个抽象类,此类继承AbstractInterruptibleChannel,实现了SeekableByteChannel、GatheringByteChannel、ScatteringByteChannel三个接口。

创建FileChannel对象,底层调用的是FileChannelImpl的构造函数。

3.1 RandomAccessFile模式

RandomAccessFile的模式有四种:r、rw、rws、rwd。

  • r:只能读。
  • rw:可读,可写。
  • rws:可读可写,每次改动都强制保存,在写入的时候会将操作系统对该文件的元数据也一起刷盘,体现就是文件的更新时间会修改。
  • rwd:可读,可写,每次改动都强制保存。

3.2 重要方法

3.2.1 open()

此方法通过文件系统创建一个FileChannel。

此方法有两个重载如下:

  • open(Path, Set<? extends OpenOption>, FileAttribute<?>...)
  • open(Path, OpenOption...)
3.2.2 read()

读取缓冲区中的内容,重载的方法大部分都是抽象方法,等待子类进行实现。

重载方法如下:

  • read(ByteBuffer)
  • read(ByteBuffer, long)
  • read(ByteBuffer[], int, int)
  • read(ByteBuffer[])
3.2.3 write()

将缓冲区中的内容写出,重载的方法大部分都是抽象方法,等待子类进行实现。

重载方法如下:

  • write(ByteBuffer)
  • write(ByteBuffer, long)
  • write(ByteBuffer[], int, int)
  • write(ByteBuffer[])
3.2.4 position()

返回这个通道中文件的当前位置。

3.2.5 position(long)

设置一个通道中文件的当前位置。

3.2.6 size()

返回当前通道中,文件的大小。

3.2.7 truncate(long)

将此通道中的文件截断为指定的大小。

3.2.8 force(boolean)

将通道内的更新内容强制写入存储设备中。

3.2.9 transferTo(long, long, WritableByteChannel)

将文件中的内容传送到写通道中。

3.2.10 transferFrom(ReadableByteChannel, long, long)

将通道中的内容传送到读通道中。

3.2.11 lock()

获取此通道给定的锁。有两个重载的方法。

  • lock(long, long, boolean)
  • lock()
3.2.12 tryLock()

尝试获取此通道给定的锁,有两个重载方法。

  • tryLock(long, long, boolean)
  • tryLock()

3.3 案例

代码语言:javascript
复制
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

	public static void fctest(String file, String mod) throws Exception {
		// 打开文件
		RandomAccessFile raf = new RandomAccessFile(file, mod);
		// 获取一个通道
		FileChannel fc = raf.getChannel();
		// 创建缓冲区
		ByteBuffer buffer = ByteBuffer.allocate(16);
		// 存入缓冲区数据
		buffer.put("FileChannelTest".getBytes(StandardCharsets.UTF_8));
		// 将缓冲区切换成读模式
		buffer.flip();
		// 将缓冲区中的数据通过通道写出
		fc.write(buffer);
		// 清空缓冲区
		buffer.clear();
		// 读取缓冲区数据
		fc.read(buffer);
		fc.close();
		raf.close();
	}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/04/09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NIO之Channel通道(一)-Channel、FileChannel
    • 1 获取通道的方式
      • 1.1 getChannel()
      • 1.2 open()
      • 1.3 newByteChannel()
      • 1.4 数据传输
      • 1.5 分散与聚集
      • 1.6 字符集
    • 2 Channel
      • 2.1 重要方法
    • 3 FileChannel
      • 3.1 RandomAccessFile模式
      • 3.2 重要方法
      • 3.3 案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档