Java NIO 之 FileChannel

 2022-08-17
原文地址:https://cloud.tencent.com/developer/article/1362837

从 JDK1.4 开始(2002 年发布的),Java 提供了 NIO ,主要包含在 java.nio 软件包及其子包中,并被命名为 New I/O(NIO)距今已经十几年了,其实已经算不得新了。

Java NIO 网上有很多详细的文档和书籍。

NIO 中的 Channel 可以分成 2 类,

  • 一类是阻塞的,只有 FileChannel
  • 一类是非阻塞的(除了 FileChannel),此类一般与 Selector 一起使用,通常是和网络相关的操作。

FileChannel

FileChannel 虽然是阻塞的,但是通常他在性能上有更好的表现。它可以通过 map 方法实现内存映射,直接提升了效率。

操作系统中,把系统的空间分成用户空间和内核空间。所谓内核空间,指的是操作系统所在的区域,里面的操作和操作系统密切相关,属于底层调用,包括和硬件的I/O交互,设置指令,线程调度等操作。而用户空间,就是常规进程所在的区域,JVM就属于常规进程,运行在用户空间。用户空间的操作不能干扰内核空间的操作,所以用户空间不能直接和硬件通信,必须通过内核空间作为中间人。正式由于这种机制,传统的文件I/O不得不在内核空间内核空间拷贝数据。

但是,还有一种操作系统支持的特殊类型的I/O操作,它直接将用户空间中的内存映射到内核空间中的高速缓存页,这种方式省去了内核空间和用户空间之间的数据复制损耗。

202208172324366941.png

下面的代码演示了通过 FileChannel 的 map 方法读取内容。

    	public static void demo() throws Exception {
    		RandomAccessFile aFile = new RandomAccessFile("c:\\source.txt", "r");
    		FileChannel inChannel = aFile.getChannel();
    		// map方法映射
    		MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
    		buffer.load();
    		for (int i = 0; i < buffer.limit(); i++) {
    			System.out.print((char) buffer.get());
    		}
    		buffer.clear();
    		// 关闭channel
    		inChannel.close();
    		aFile.close();
    	}
复制代码

原创文章,转载请注明出处!http://www.javathings.top/java-nio之filechannel/