# Java NIO(一)FileChannel

Java NIO

1.BIO与NIO的区别

BIO为阻塞IO,NIO为非阻塞IO。

BIO NIO
JAVA1.4之前 Java 1.4之后
面向流:以byte为单位处理数据 面向块:以块为单位处理数据
同步阻塞 同步非阻塞
选择器(Selector)

1.1NIO的核心组成部分

  • Channels
    Channel是双向的,既能做读操作也能做写操作,常见Channel如下:
Channel类 功能
FileChannel 文件数据读写
DtagramChannel UDP数据读写
ServerScoketChannel和SocketChannel TCP数据读写
  • Buffers
    缓冲区
  • Selectors
    选择器,用于监听多个通道的事件,可实现单个线程就可以监听多个客户端通道。

2.Channel

Channel封装了对数据源的操作,可以操作多种数据源,但是不必关心数据源的具体物理结构。Channel用于在字节缓冲区和另一侧的实体之间有效地传输数据。

Channel所有数据都是通过Buffer对象进行处理,通道要么读数据到缓冲区,要么从缓冲区写入到通道。

java 复制代码
public interface Channle extend Closeable {
	public boolean isOpen();
	public void close() throws IOException;
}
2.1 FileChannel

FileChannel常用方法如下;

方法名 作用
public int read(ByteBuffer dst) 从通道读取数据并放到缓冲区中
public int write(ByteBuffer src) 把缓冲区的数据写到通道中
public long transferFrom(ReadableByteChannel src, long position, long count) 从目标通道中复制数据到当前通道
public long transferTo(long position, long count, WritableByteChannel target) 把数据从当前通道复制给目标通道

无法直接打开一个FileChannel,常见的方法是通过inPutStream和outPutStream或RandomAccessFile获取一个FileChannel实例。
示例代码
文件写入示例

java 复制代码
package com.hero.nio.file;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
//通过NIO实现文件IO
public class TestNIO {
@Test //往本地文件中写数据
public void test1() throws Exception{
	//1. 创建输出流
	FileOutputStream fos=new FileOutputStream("basic.txt");
	//2. 从流中得到一个通道
	FileChannel fc=fos.getChannel();
	//3. 提供一个缓冲区
	ByteBuffer buffer=ByteBuffer.allocate(1024);
	//4. 往缓冲区中存入数据
	String str="HelloJava";
	buffer.put(str.getBytes());
	//5. 翻转缓冲区
	buffer.flip();
	while(buffer.hasRemaining()) {
	//6. 把缓冲区写到通道中
		fc.write(buffer);
	}
	//7. 关闭
	fos.close();
	}
}

文件复制示例

java 复制代码
public void test4() throws Exception {
	//1. 创建两个流
	FileInputStream fis = new FileInputStream("basic2.txt");
	FileOutputStream fos = new FileOutputStream("basic3.txt");
	//2. 得到两个通道
	FileChannel sourceFC = fis.getChannel();
	FileChannel destFC = fos.getChannel();
	//3. 复制
	destFC.transferFrom(sourceFC, 0, sourceFC.size());
	//4. 关闭
	fis.close();
	fos.close();
}
相关推荐
serendipity_hky4 分钟前
【SpringCloud | 第2篇】OpenFeign远程调用
java·后端·spring·spring cloud·openfeign
RwTo7 分钟前
【源码】-Java线程池ThreadPool
java·开发语言
SadSunset9 分钟前
(15)抽象工厂模式(了解)
java·笔记·后端·spring·抽象工厂模式
兮动人12 分钟前
EMT4J定制规则版:Java 8→17迁移兼容性检测与规则优化实战
java·开发语言·emt4j
一点★13 分钟前
Java中的常量池和字符串常量池
java·开发语言
问君能有几多愁~34 分钟前
C++ 日志实现
java·前端·c++
菜鸟plus+37 分钟前
Java 接口的演变
java·开发语言
李慕婉学姐38 分钟前
【开题答辩过程】以《基于springboot的地铁综合服务管理系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·spring boot·后端
IT空门:门主1 小时前
Spring AI的教程,持续更新......
java·人工智能·spring·spring ai
期待のcode1 小时前
Springboot配置属性绑定
java·spring boot·后端