NIO流
NIO流:NIO 支持面向缓冲区的、基于通道的 IO 操作。 NIO 将以更加高效的方式进行文件的读写操作。
IO 与 NIO 的区别:
IO:
面向流(StreamOriented)
阻塞IO(BlockingIO)
NIO:
面向缓冲区(BufferOriented)
非阻塞IO(NonBlockingIO)
选择器(Selectors)
通道 (Channel) 和缓冲区(Buffer):
Channel 负责传输, Buffer 负责存储
1、通道表示打开到 IO 设备 ( 例如:文件、套接字 ) 的连接
2、缓冲区主要用于与 NIO 通道进行交互,数据是从通道读入缓冲区,从缓冲区写入通道中的。
缓冲区的基本属性:
1、容量 (capacity):表示 Buffer 最大数据容量,缓冲区容量不能为负,并且创
建后不能更改。
2、限制 (limit):第一个不应该读取或写入的数据的索引,即位于 limit 后的数据
不可读写。缓冲区的限制不能为负,并且不能大于其容量。
3、位置 (position): 一个要读取或写入的数据的索引。缓冲区的位置不能为负,
并且不能大于其限制
4、标记 (mark) 与重置 (reset):标记是一个索引,通过 Buffer 中的 mark() 方法
指定 Buffer 中一个特定的 position ,之后可以通过调用 reset() 方法恢复到这
个 position.
缓冲区常用方法:
put() : 存入数据到缓冲区中
put(byte b) :将给定单个字节写入缓冲区的当前位置
put(byte[] src) :将 src 中的字节写入缓冲区的当前位置
put(int index, byte b) :将指定字节写入缓冲区的索引位置 ( 不会移动 position)
get() : 获取缓冲区中的数据
get(byte[] dst) :批量读取多个字节到 dst 中
get(int index) :读取指定索引位置的字节 ( 不会移动 position)
flip(); 切换读取数据模式
rewind() : 可重复读
clear() : 清空缓冲区. 但是缓冲区中的数据依然存在,但是处于“被遗忘”状态
mark() : 标记是一个索引,通过 Buffer中的mark() 方法,指定 Buffer中一
个特定的 position,之后可以通过调用 reset() 方法恢复到这个position.
获取通道的方式:
一、通过getChannel()方法获取通道:
public class test1 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("蓝莲花.mp3");
FileOutputStream out = new FileOutputStream("蓝莲花1.mp3");
FileChannel inChannel = in.getChannel();
FileChannel outChannel = out.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (inChannel.read(byteBuffer) != -1) {
byteBuffer.flip();
outChannel.write(byteBuffer);
byteBuffer.clear();
}
in.close();
out.close();
inChannel.close();
outChannel.close();
}
}
二、通过 FileChannel 中的 静态方法 open() 可以打开通道:
public class test2 {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("D:\\蓝莲花.mp3"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("E:\\蓝莲花.mp3"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (inChannel.read(byteBuffer) != -1) {
byteBuffer.flip();
outChannel.write(byteBuffer);
byteBuffer.clear();//清空缓冲区
}
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("耗时"+(end-start)+"毫秒");
}
}
三、 通过Files.newByteChannel( )或Channels.newChannel():
public class test3 {
public static void main(String[] args) throws IOException {
FileChannel channel = new FileInputStream("a.txt").getChannel();
FileChannel.open()
SeekableByteChannel seekableByteChannel = Files.newByteChannel(Paths.get("a.txt"), StandardOpenOption.READ);
Channels.newChannel()
}
}
Files类:
常用方法:
1、
Path copy(Path src, Path dest, CopyOption … how) : 文件的复制
Path createDirectory(Path path, FileAttribute<?> … attr) :创建一个目录
Path createFile(Path path, FileAttribute<?> … arr) : 创建一个文件
void delete(Path path) : 删除一个文件
Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置
long size(Path path) : 返回 path 指定文件的大小
2、用于判断
boolean exists(Path path, LinkOption … opts) : 判断文件是否存在
boolean isDirectory(Path path, LinkOption … opts) :判断是否是目录
boolean isExecutable(Path path) : 判断是否是可执行文件
boolean isHidden(Path path) : 判断是否是隐藏文件
boolean isReadable(Path path) : 判断文件是否可读
boolean isWritable(Path path) : 判断文件是否可写
boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在
public static <A extends BasicFileAttributes> A readAttributes(Path path,Class<A> type,LinkOption...
options) : 获取与 path 指定的文件相关联的属性。
3、用于操作内容
SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接,how 指定打开方式。
DirectoryStream newDirectoryStream(Path path) : 打开 path 指定的目录
InputStream newInputStream(Path path, OpenOption…how): 获取 InputStream 对象
OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象
Path 常用方法:
1、Paths 提供的get()方法用来获取Path对象
Path get(String first,String… more): 用于将多个字符串串连成路
2、
boolean endsWith(String path) : 判断是否以 path 路径结束
boolean startsWith(String path) : 判断是否以 path 路径开始
boolean isAbsolute() : 判断是否是绝对路径
Path getFileName() : 返回与调用 Path 对象关联的文件名
Path getName(int idx) : 返回的指定索引位置 idx 的路径名称
int getNameCount() : 返回 Path 根目录后面元素的数量
Path getParent() : 返回 Path 对象包含整个路径,不包含 Path 对象指定的文件路径
Path getRoot() : 返回调用 Path 对象的根路径
Path resolve(Path p) : 将相对路径解析为绝对路径
Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象
String toString() : 返回调用 Path 对象的字符串表示形式
通过Files中的方法复制文件:
public class MyTest {
public static void main(String[] args) throws IOException {
//static long copy (InputStream in, Path target, CopyOption...options)
//将所有字节从输入流复制到文件。
//static long copy (Path source, OutputStream out)
//将从文件到输出流的所有字节复制到输出流中。
//static Path copy (Path source, Path target, CopyOption...options)
//将一个文件复制到目标文件。
Files.copy(new FileInputStream("蓝莲花.mp3"),Paths.get("蓝莲花1.mp3"));
Files.copy(Paths.get("上海滩.mp3"),new FileOutputStream("上海滩2.mp3"));
Files.copy(Paths.get("E:\\蓝莲花.mp3"),Paths.get("E:\\蓝莲花3.mp3"));
}
}