# 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();
}
相关推荐
身如柳絮随风扬27 分钟前
多数据源切换实战:从业务场景到3种实现方案全解析
java·分布式·微服务
Java小生不才1 小时前
Spring AI文生音
java·人工智能·spring
凯尔萨厮1 小时前
Springboot2.x+Thymeleaf项目创建
java
fish_xk1 小时前
map和set
java·开发语言
李崧正1 小时前
Java技术分享:Lambda表达式与函数式编程
java·开发语言·python
老了,不知天命2 小时前
鳶尾花項目JAVA
java·开发语言·机器学习
二哈赛车手2 小时前
新人笔记---实现简易版的rag的bm25检索(利用ES),以及RAG上传时的ES与向量数据库双写
java·数据库·笔记·spring·elasticsearch·ai
winner88812 小时前
从零吃透C++命名空间、std、#include、string、vector
java·开发语言·c++
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题】【Java基础篇】第26题:Java的抽象类和接口有哪些区别
java·开发语言·面试
bzmK1DTbd2 小时前
SOLID原则在Java中的实践:单一职责与开闭原则
java·开发语言·开闭原则