1.概述

Java NIO(New IO) 是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。
NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同, NIO支持面向缓冲区的、基于通道的IO操作。 NIO将以更加高效的方式进行文件的读写操作。

Java NIO系统的核心在于:

  通道(Channel)和缓冲区(Buffer)。

  通道表示打开到 IO 设备(例如:文件、套接字)的连接。

  若需要使用 NIO 系统,需要获取用于连接 IO 设备的通道以及用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。

简而言之, Channel 负责传输Buffer 负责存储

 Buffer 中的重要概念:
 容量 (capacity) : 表示 Buffer 最大数据容量,缓冲区容量不能为负,并且创
建后不能更改。
 限制 (limit): 第一个不应该读取或写入的数据的索引,即位于 limit 后的数据
不可读写。缓冲区的限制不能为负,并且不能大于其容量。
 位置 (position): 下一个要读取或写入的数据的索引。缓冲区的位置不能为
负,并且不能大于其限制
 标记 (mark)与重置 (reset): 标记是一个索引,通过 Buffer 中的 mark() 方法
指定 Buffer 中一个特定的 position,之后可以通过调用 reset() 方法恢复到这
个 position.
 标记、 位置、 限制、 容量遵守以下不变式: 0 <= mark <= position <= limit <= capacity

2.NIO与IO的区别

NIO

传统的IO

 3.缓冲区(buffer)

package com.zy.nio;

import org.junit.Test;

import java.nio.ByteBuffer;

/*
* 一、缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据
*
* 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区:
* ByteBuffer
* CharBuffer
* ShortBuffer
* IntBuffer
* LongBuffer
* FloatBuffer
* DoubleBuffer
*
* 上述缓冲区的管理方式几乎一致,通过 allocate() 获取缓冲区
*
* 二、缓冲区存取数据的两个核心方法:
* put() : 存入数据到缓冲区中
* get() : 获取缓冲区中的数据
*
* 三、缓冲区中的四个核心属性:
* capacity : 容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。
* limit : 界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写)
* position : 位置,表示缓冲区中正在操作数据的位置。
*
* mark : 标记,表示记录当前 position 的位置。可以通过 reset() 恢复到 mark 的位置
*
* 0 <= mark <= position <= limit <= capacity
*
* 四、直接缓冲区与非直接缓冲区:
* 非直接缓冲区:通过 allocate() 方法分配缓冲区,将缓冲区建立在 JVM 的内存中
* 直接缓冲区:通过 allocateDirect() 方法分配直接缓冲区,将缓冲区建立在物理内存中。可以提高效率
*/
public class NioBufferDemo01 { @Test
public void fn03(){
// 间接缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 直接缓冲区
ByteBuffer diretBuffer = ByteBuffer.allocateDirect(1024);
System.out.println(buffer.isDirect());
System.out.println(diretBuffer.isDirect());
} @Test
public void fn02(){
String str = "qwertyuiop";
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put(str.getBytes());
buffer.flip(); byte[] b = new byte[buffer.limit()];
buffer.get(b, 0, 2);
System.out.println(new String(b, 0, 2));
System.out.println(buffer.position()); // mark:标记
System.out.println("-----------------mark()----------------");
buffer.mark();
buffer.get(b, 2, 2);
System.out.println(new String(b, 2, 2));
System.out.println(buffer.position()); // reset:恢复到mark的位置
System.out.println("-----------------reset()----------------");
buffer.reset();
System.out.println(buffer.position()); //判断缓冲区中是否还有剩余数据
System.out.println("-----------------hasRemaining()----------------");
System.out.println("-----------------remaining()----------------");
if (buffer.hasRemaining()){
System.out.println(buffer.remaining());
}
} @Test
public void fn01(){ String string = "zxcvbnm"; //1. 分配一个指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024); System.out.println("-----------------allocate()----------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //2. 利用 put() 存入数据到缓冲区中
buffer.put(string.getBytes());
System.out.println("-----------------put()----------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //3. 切换读取数据模式
buffer.flip();
System.out.println("------------------flip()-------------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //4. 利用 get() 读取缓冲区中的数据
byte[] b = new byte[buffer.limit()];
buffer.get(b);
System.out.println(new String(b, 0, b.length)); System.out.println("------------------get()-------------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //5. rewind() : 可重复读
buffer.rewind(); System.out.println("-----------------rewind()----------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); //6. clear() : 清空缓冲区. 但是缓冲区中的数据依然存在,但是处于“被遗忘”状态
buffer.clear(); System.out.println("------------------clear()------------------------");
System.out.println(buffer.position());
System.out.println(buffer.limit());
System.out.println(buffer.capacity()); System.out.println((char)buffer.get());
} }

4.通道

通道(Channel):由 java.nio.channels 包定义的。 Channel 表示 IO 源与目标打开的连接。

Channel 类似于传统的“流”。只不过 Channel本身不能直接访问数据, Channel 只能与Buffer 进行交互。

本身不存储任何数据,需要配合缓冲区才能完成数据传输。

package com.zy.nio;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.SortedMap; /*
* 一、通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。
*
* 二、通道的主要实现类
* java.nio.channels.Channel 接口:
* |--FileChannel 用于读取、写入、映射和操作文件的通道。
* |--SocketChannel 通过 TCP 读写网络中的数据
* |--ServerSocketChannel 可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel
* |--DatagramChannel 通过 UDP 读写网络中的数据通道
*
* 三、获取通道有三种方式
* 1. Java 针对支持通道的类提供了 getChannel() 方法
* 本地 IO:
* FileInputStream/FileOutputStream
* RandomAccessFile
*
* 网络IO:
* Socket
* ServerSocket
* DatagramSocket
*
* 2. 在 JDK 1.7 中的 NIO.2 针对各个通道提供了静态方法 open()
* 3. 在 JDK 1.7 中的 NIO.2 的 Files 工具类的 newByteChannel()
*
* 四、通道之间的数据传输
* transferFrom()
* transferTo()
*
* 五、分散(Scatter)与聚集(Gather)
* 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
* 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到通道中
*
* 六、字符集:Charset
* 编码:字符串 -> 字节数组
* 解码:字节数组 -> 字符串
*
*/
public class NioChannelDemo01 { // 6.指定字符集的编码与解码
@Test
public void fn06() throws Exception {
Charset charset = Charset.forName("utf-8");
// 获取编码器
CharsetEncoder encoder = charset.newEncoder();
// 获取解码器
CharsetDecoder decoder = charset.newDecoder();
CharBuffer cBuffer = CharBuffer.allocate(1024);
cBuffer.put("好好学习,天天向上");
cBuffer.flip();
// 编码
ByteBuffer bBuffer = encoder.encode(cBuffer);
// 解码
bBuffer.flip();
CharBuffer charBuffer = decoder.decode(bBuffer);
System.out.println(charBuffer); } // 5.遍历所有支持的字符集
@Test
public void fn05(){
SortedMap<String, Charset> charsets = Charset.availableCharsets();
charsets.forEach((k,v)->{
System.out.println("item:"+k+"===============value:"+v);
});
} // 4.分散读取与聚集写入
@Test
public void fn04() throws Exception{
RandomAccessFile raf = new RandomAccessFile("E:/idea.txt", "rw");
// 获取通道
FileChannel channel = raf.getChannel();
// 分配指定的缓冲区的大小
ByteBuffer buffer = ByteBuffer.allocate(100);
ByteBuffer buffer1 = ByteBuffer.allocate(1024);
// 分散读取
ByteBuffer[] buffers = {buffer, buffer1};
channel.read(buffers);
for (ByteBuffer bf : buffers){
bf.flip();
}
System.out.println("==================分散读取开始====================");
System.out.println(new String(buffers[0].array(), 0, buffers[0].limit()));
System.out.println(new String(buffers[1].array(), 0, buffers[1].limit()));
System.out.println("==================分散读取结束===================="); // 聚集写入
RandomAccessFile raf2 = new RandomAccessFile("E:/idea01.txt", "rw");
FileChannel channel1 = raf2.getChannel();
channel1.write(buffers); } // 3.使用直接缓冲区完成文件的复制(较为简便的方式)
@Test
public void fn03(){
FileChannel in = null;
FileChannel out = null;
try {
in = FileChannel.open(Paths.get("E:/1.png"), StandardOpenOption.READ);
out = FileChannel.open(Paths.get("E:/4.png"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE); // 方法一: in.transferTo(0, in.size(), out);
// 方法二:
out.transferFrom(in, 0, in.size());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} // 2.使用直接缓冲区完成文件的复制(内存映射文件)(较为复杂的方式,少用)
/*建议将直接缓冲区主要分配给那些易受基础系统的本机 I/O 操作影响的大型、持久的缓冲区。
一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们*/
@Test
public void fn02(){
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = FileChannel.open(Paths.get("E:/1.png"), StandardOpenOption.READ);
outChannel = FileChannel.open(Paths.get("E:/3.png"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
// 内存映射文件,只支持byteBuffer
MappedByteBuffer inMapBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMapBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] b = new byte[inMapBuffer.limit()];
inMapBuffer.get(b);
outMapBuffer.put(b);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inChannel.close();
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
} } // 1.利用通道完成文件的复制(非直接缓冲区)
@Test
public void fn01(){
FileInputStream is = null;
FileOutputStream os = null;
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
is = new FileInputStream("E:/1.png");
os = new FileOutputStream("E:/2.png");
// 获取通道
inChannel = is.getChannel();
outChannel = os.getChannel();
// 分配指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 将通道中的数据存入缓冲区中
while (inChannel.read(buffer) != -1){
// 切换读取数据的模式
buffer.flip();
// 将缓冲区的数据写入通道中
outChannel.write(buffer);
// 清空缓冲区
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outChannel.close();
inChannel.close();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

5.Blocking NIO

package com.zy.nio;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; /*
* 一、使用 NIO 完成网络通信的三个核心:
*
* 1. 通道(Channel):负责连接
*
* java.nio.channels.Channel 接口:
* |--SelectableChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
* |--Pipe.SinkChannel
* |--Pipe.SourceChannel
*
* 2. 缓冲区(Buffer):负责数据的存取
*
* 3. 选择器(Selector):是 SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况
*
*/
public class BlockNioDemo01 { // 客户端
@Test
public void client() throws IOException {
// 1.获取通道
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8888));
FileChannel inChannel = FileChannel.open(Paths.get("E:/1.png"), StandardOpenOption.READ);
// 2.分配指定的缓冲区的大小
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 3.读取本地文件,并发送到服务端
while (inChannel.read(buffer) != -1){
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
// 4.关闭通道
inChannel.close();
socketChannel.close();
} // 服务端
@Test
public void server() throws IOException {
// 1.获取通道
ServerSocketChannel channel = ServerSocketChannel.open();
FileChannel outChannel = FileChannel.open(Paths.get("E:/5.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
// 2.绑定连接
channel.bind(new InetSocketAddress(8888));
// 3.获取客户端连接的通道
SocketChannel clientChannel = channel.accept();
// 4.分配指定的缓冲区的大小
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 5.接收客户端的数据并保存到本地
while (clientChannel.read(buffer) != -1){
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
// 6.关闭资源
clientChannel.close();
outChannel.close();
channel.close(); } }
package com.zy.nio;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; /**
*
* 阻塞式NIO2
*/
public class BlockNio2Demo01 { // 客户端
@Test
public void client() throws IOException {
// 1.获取通道
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9999));
FileChannel fileChannel = FileChannel.open(Paths.get("E:/1.png"), StandardOpenOption.READ);
// 2.分配指定的缓冲区的大小
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 3.读取本地文件,并发送到服务端
while (fileChannel.read(buffer) != -1){
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
socketChannel.shutdownOutput();
// 4.接收服务端的反馈
int len = 0;
while ((len = socketChannel.read(buffer)) != -1){
buffer.flip();
System.out.println(new String(buffer.array(), 0, len));
buffer.clear();
}
// 5.关闭资源
fileChannel.close();
socketChannel.close();
} // 服务端
@Test
public void server() throws IOException {
// 1.获取通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
FileChannel fileChannel = FileChannel.open(Paths.get("E:/6.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
// 2.绑定连接
serverSocketChannel.bind(new InetSocketAddress(9999));
// 3.获取客户端连接的通道
SocketChannel socketChannel = serverSocketChannel.accept();
// 4.分配指定缓冲区的大小
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 5.将客户端的资源保存到本地
while (socketChannel.read(buffer) != -1){
buffer.flip();
fileChannel.write(buffer);
buffer.clear();
}
// 6.发送反馈给客户端
buffer.put("服务端数据接收成功".getBytes());
buffer.flip();
socketChannel.write(buffer);
// 7.关闭资源
socketChannel.close();
fileChannel.close();
serverSocketChannel.close(); }
}

6.Non-Blocking NIO

TCP

package com.zy.nio;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.Scanner; /*
* 一、使用 NIO 完成网络通信的三个核心:
*
* 1. 通道(Channel):负责连接
*
* java.nio.channels.Channel 接口:
* |--SelectableChannel
* |--SocketChannel
* |--ServerSocketChannel
* |--DatagramChannel
*
* |--Pipe.SinkChannel
* |--Pipe.SourceChannel
*
* 2. 缓冲区(Buffer):负责数据的存取
*
* 3. 选择器(Selector):是 SelectableChannel 的多路复用器。用于监控 SelectableChannel 的 IO 状况
*
* 非阻塞式NIO
*/
public class NonBlockNioDemo01 { // 客户端
@Test
public void client() throws IOException {
// 1.获取通道
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9090));
// 2.切换为非阻塞模式
socketChannel.configureBlocking(false);
// 3.分配指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 4.发送消息到服务器
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
String str = scanner.next();
buffer.put((LocalDateTime.now().toString()+"\n"+str).getBytes());
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
// 5.关闭通道
socketChannel.close();
} // 服务端
@Test
public void server() throws IOException {
// 1.获取通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 2.切换为非阻塞模式
serverSocketChannel.configureBlocking(false);
// 3.绑定连接
serverSocketChannel.bind(new InetSocketAddress(9090));
// 4.获取选择器
Selector selector = Selector.open();
// 5.将通道注册到选择器上,指定监听事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
// 6.轮询式的获取选择器上准备就绪的事件
while (selector.select() > 0){
// 7.获取当前选择器中所有注册的选择键(已就绪的监听事件)
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
// 8.迭代获取准备就绪的事件
while (keyIterator.hasNext()){
SelectionKey next = keyIterator.next();
// 9.判断具体是什么事件准备就绪
if (next.isAcceptable()){
// 10.若接收就绪,则获取客户端连接
SocketChannel socketChannel = serverSocketChannel.accept();
// 11.切换为非阻塞模式
socketChannel.configureBlocking(false);
// 12.将该通道注册到选择器上
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (next.isReadable()){
// 获取读就绪通道
SocketChannel channel = (SocketChannel) next.channel();
// 读取数据
ByteBuffer buffer = ByteBuffer.allocate(1024);
int len = 0;
while ((len = channel.read(buffer)) > 0){
buffer.flip();
System.out.println(new String(buffer.array(), 0, len));
buffer.clear();
}
}
// 取消选择键
keyIterator.remove();
}
}
}
}

UDP

package com.zy.nio;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.time.LocalDateTime;
import java.util.Iterator;
import java.util.Scanner; /**
* UDP-NIO
*/
public class NonBlockNioDemo02 { // 客户端
@Test
public void client() throws IOException {
// 1.获取通道
DatagramChannel datagramChannel = DatagramChannel.open();
// 2.切换为非阻塞模式
datagramChannel.configureBlocking(false);
// 3.分配指定的缓冲区大小
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 4.发送消息到服务器
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
String next = scanner.next();
buffer.put((LocalDateTime.now().toString()+"\n"+next).getBytes());
buffer.flip();
datagramChannel.send(buffer, new InetSocketAddress("127.0.0.1",9090));
buffer.clear();
}
// 5.关闭资源
datagramChannel.close();
} // 服务端
@Test
public void server() throws IOException {
// 1.获取通道
DatagramChannel datagramChannel = DatagramChannel.open();
// 2.切换为nio状态
datagramChannel.configureBlocking(false);
// 3.绑定连接
datagramChannel.bind(new InetSocketAddress(9090));
// 4.获得选择器
Selector selector = Selector.open();
// 5.将通道注册到选择器上,并绑定监听事件
datagramChannel.register(selector, SelectionKey.OP_READ);
// 6.通过轮询方式获取选择器上准备就绪的事件
while (selector.select() > 0){
Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while (it.hasNext()){
SelectionKey next = it.next();
if (next.isReadable()){
ByteBuffer buffer = ByteBuffer.allocate(1024);
datagramChannel.receive(buffer);
buffer.flip();
System.out.println(new String(buffer.array(), 0, buffer.limit()));
buffer.clear();
}
}
it.remove();
}
} }

7.管道 (Pipe)
Java NIO 管道是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写到sink通道,从source通道读取。

package com.zy.nio;

import org.junit.Test;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe; public class PipeNioDemo01 { @Test
public void fn() throws IOException {
// 1.获取管道
Pipe pipe = Pipe.open();
// 2.将缓冲区中的数据写入管道
ByteBuffer buffer = ByteBuffer.allocate(1024);
Pipe.SinkChannel sinkChannel = pipe.sink();
buffer.put("通过单向管道发送数据".getBytes());
buffer.flip();
sinkChannel.write(buffer);
// 3.读取管道缓冲区中的数据
Pipe.SourceChannel sourceChannel = pipe.source();
buffer.flip();
int len = sourceChannel.read(buffer);
System.out.println(new String(buffer.array(), 0, len));
sourceChannel.close();
sinkChannel.close();
}
}

8.NIO2

8.1Path Paths
java.nio.file.Path 接口代表一个平台无关的平台路径,描述了目录结构中文件的位置。
Paths 提供的 get() 方法用来获取 Path 对象:
 Path get(String first, String … more) : 用于将多个字符串串连成路径。
Path 常用方法:
 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 对象的字符串表示形式

8.2Files
 java.nio.file.Files 用于操作文件或目录的工具类。
Files常用方法:
 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 指定文件的大小

Files常用方法:用于判断
 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 指定的文件相关联的属性。

Files常用方法: 用于操作内容
 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 对象

8.3自动资源管理

Java 7 增加了一个新特性,该特性提供了另外一种管理资源的方式,这种方式能自动关闭文件。

这个特性有时被称为自动资源管理(Automatic Resource Management, ARM), 该特性以 try 语句的扩展版为基础。

自动资源管理主要用于,当不再需要文件(或其他资源)时,可以防止无意中忘记释放它们。

Java中的NIO及IO的更多相关文章

  1. java中的NIO和IO到底是什么区别?20个问题告诉你答案

    摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...

  2. JAVA中的NIO (New IO)

    简介 标准的IO是基于字节流和字符流进行操作的,而JAVA中的NIO是基于Channel和Buffer进行操作的. 传统IO graph TB; 字节流 --> InputStream; 字节流 ...

  3. Java中的NIO和IO的对比分析

    总的来说,java中的IO和NIO主要有三点区别: IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的 ...

  4. Java中的NIO基础知识

    上一篇介绍了五种NIO模型,本篇将介绍Java中的NIO类库,为学习netty做好铺垫 Java NIO 由3个核心组成,分别是Channels,Buffers,Selectors.本文主要介绍着三个 ...

  5. 关于Java中面向对象章节、IO 流中的重点基础知识。

    一.面向对象的三大特征,以及作用. 答:面向对象的三大特征即,封装性.继承性.多态性. 其分别的作用为 : 封装作用:将数据封装起来,提高数据的安全性, 继承作用:提高代码的复用性,减少冗余代码. 多 ...

  6. 再谈一次关于Java中的 AIO(异步IO) 与 NIO(非阻塞IO)

    今天用ab进行压力测试时,无意发现的: Requests per second:    xxx [#/sec] (mean) ab -n 5000 -c 1000 http://www:8080/up ...

  7. JAVA中的NIO(二)

    一.内存文件映射 内存文件映射允许我们创建和修改那些因为太大而不能放入内存中的文件.有了内存文件映射,我们就可以假定整个文件都在内存中,而且可以完全把文件当作数组来访问. package com.dy ...

  8. JAVA中的NIO(一)

    1.IO与NIO IO就是普通的IO,或者说原生的IO.特点:阻塞式.内部无缓冲,面向流. NIO就是NEW IO,比原生的IO要高效.特点:非阻塞.内部有缓存,面向缓冲. 要实现高效的IO操作,尤其 ...

  9. JAVA 中BIO,NIO,AIO的理解

    [转自]http://qindongliang.iteye.com/blog/2018539 ?????????????????????在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解 ...

随机推荐

  1. JQUERY dialog的用法详细解析

    本篇文章主要是对JQUERY中dialog的用法进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助 今天用到了客户端的对话框,把 jQuery UI 中的对话框学习了一下. 准备 jQ ...

  2. System.Security.Authentication.AuthenticationException:根据验证过程,远程证书无效。

    好久没写博客了,今天突然遇到个神奇的问题. 做好的网站在win10上和Windows sever 2012 上都没有问题,搬到Windows sever 2003上就出现了这么一个错误: Server ...

  3. 网络文件系统与 Linux

    网络文件系统 是文件系统之上的一个网络抽象,来允许远程客户端以与本地文件系统类似的方式,来通过网络进行访问.虽然 NFS 不是第一个此类系统,但是它已经发展并演变成 UNIX® 系统中最强大最广泛使用 ...

  4. C++官方文档-运算符重载

    #include <iostream> using namespace std; class CVector { public: int x, y; CVector() : x(), y( ...

  5. 9.简单理解ajax

    #### post 请求需要发送一个header setRequestHeader('Content-Type','application/x-www-form-urlencoded') post请求 ...

  6. CUDA C Programming Guide 在线教程学习笔记 Part 10【坑】

    ▶ 动态并行. ● 动态并行直接从 GPU 上创建工作,可以减少主机和设备间数据传输,在设备线程中调整配置.有数据依赖的并行工作可以在内核运行时生成,并利用 GPU 的硬件调度和负载均衡.动态并行要求 ...

  7. jsfl 第一天

    ctrl+f10,打开操作记录 通过打开到目标fla的舞台,然后运行写好的jsfl,默认就以目标fla为调试对象. 通过name可以获取层名字,帧标签,元件实例名等,name属性要根据对象的应用而产生 ...

  8. jdk升级到9,eclipse打不开

    jdk从1.8到1.9之后删除了不少之前Deprecated的类. eclipse 版本oxygen和neon对应jdk1.8 eclipse 版本luna和mars对应jdk1.7,1.6 在打开e ...

  9. 5 python 内置类

    1.实例属性和类属性 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Chinese: def __init__(self,name,sex,age): self.name = ...

  10. UI5-文档-4.4-XML Views

    将所有UI放到index.html文件将很快导致一个混乱的设置,有相当多的工作在我们前面.我们先用sap.m.Text进行模块化.控件导入专用视图. SAPUI5支持多种视图类型(XML.HTML.J ...