一、Java NIO 概述
1、NIO概述
Java NIO (New IO, Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO API。 NIO 与原来的IO有同样的作用和目的,但是使用的方式完全不同, NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。 NIO将以更加高效的方式进行文件的读写操作。
2、NIO 分类
Java API中提供了两套NIO, 一套是针对标准输入输出NIO, 另一套就是网络编程NIO。
3、NIO 分类
二、NIO2
随着 JDK 7 的发布, Java对NIO进行了极大的扩展,增强了对文件处理和文件系统特性的支持,以至于我们称他们为 NIO.2。因为 NIO 提供的一些功能, NIO已经成为文件处理中越来越重要的部分。
三、Path、Paths 和 Files核心 API
1、早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,所提供的方法性能也不高。而且, 大多数方法在出错时仅返回失败,并不会提供异常信息。
2、NIO. 2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。 Path可以看成是File类的升级版本,实际引用的资源也可以不存在。
以前的IO操作
import java.io.File;
File file = new File("index.html");
在Java7中,可以这样写:
import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("index.html");
3、同时, NIO.2在 java.nio.file 包下还提供了 Files、 Paths 工具类, Files 包含了大量静态的工具方法来操作文件; Paths则包含了两个返回Path的静态工厂方法
Paths 类提供的静态 get() 方法用来获取 Path 对象:
static Path get(String first, String … more) : 用于将多个字符串串连成路径
static Path get(URI uri): 返回指定uri对应的Path路径
四、Path 接口
常用方法:
String toString() : 返回调用 Path 对象的字符串表示形式
boolean startsWith(String path) : 判断是否以 path 路径开始
boolean endsWith(String path) : 判断是否以 path 路径结束
boolean isAbsolute() : 判断是否是绝对路径
Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径
Path getRoot() :返回调用 Path 对象的根路径
Path getFileName() : 返回与调用 Path 对象关联的文件名
int getNameCount() : 返回Path 根目录后面元素的数量
Path getName(int idx) : 返回指定索引位置 idx 的路径名称
Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象
Path resolve(Path p) :合并两个路径,返回合并后的路径对应的Path对象
File toFile(): 将Path转化为File类的对象
五、Files 类
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) : 删除一个文件/目录,如果不存在,执行报错
void deleteIfExists(Path 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 isRegularFile(Path path, LinkOption … opts) : 判断是否是文件
boolean isHidden(Path path) : 判断是否是隐藏文件
boolean isReadable(Path path) : 判断文件是否可读
boolean isWritable(Path path) : 判断文件是否可写
boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在
Files 常用方法:用于操作内容
SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接, how 指定打开方式。
DirectoryStream<Path> newDirectoryStream(Path path) : 打开 path 指定的目录
InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象
六、案例
1、Paths 实例化Path
1 @Test
2 public void test1() {
3 Path path1 = Paths.get("d:\\nio\\hello.txt");//new File(String filepath)
4
5 Path path2 = Paths.get("d:\\", "nio\\hello.txt");//new File(String parent,String filename);
6
7 System.out.println(path1);
8 System.out.println(path2);
9
10 Path path3 = Paths.get("d:\\", "nio");
11 System.out.println(path3);
12 }
2、Path 中的常用方法
1 @Test
2 public void test2() {
3 Path path1 = Paths.get("d:\\", "nio\\nio1\\nio2\\hello.txt");
4 Path path2 = Paths.get("hello.txt");
5
6 // String toString() : 返回调用 Path 对象的字符串表示形式
7 System.out.println(path1);
8
9 // boolean startsWith(String path) : 判断是否以 path 路径开始
10 System.out.println(path1.startsWith("d:\\nio"));
11 // boolean endsWith(String path) : 判断是否以 path 路径结束
12 System.out.println(path1.endsWith("hello.txt"));
13 // boolean isAbsolute() : 判断是否是绝对路径
14 System.out.println(path1.isAbsolute() + "~");
15 System.out.println(path2.isAbsolute() + "~");
16 // Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径
17 System.out.println(path1.getParent());
18 System.out.println(path2.getParent());
19 // Path getRoot() :返回调用 Path 对象的根路径
20 System.out.println(path1.getRoot());
21 System.out.println(path2.getRoot());
22 // Path getFileName() : 返回与调用 Path 对象关联的文件名
23 System.out.println(path1.getFileName() + "~");
24 System.out.println(path2.getFileName() + "~");
25 // int getNameCount() : 返回Path 根目录后面元素的数量
26 // Path getName(int idx) : 返回指定索引位置 idx 的路径名称
27 for (int i = 0; i < path1.getNameCount(); i++) {
28 System.out.println(path1.getName(i) + "*****");
29 }
30
31 // Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象
32 System.out.println(path1.toAbsolutePath());
33 System.out.println(path2.toAbsolutePath());
34 // Path resolve(Path p) :合并两个路径,返回合并后的路径对应的Path对象
35 Path path3 = Paths.get("d:\\", "nio");
36 Path path4 = Paths.get("nioo\\hi.txt");
37 path3 = path3.resolve(path4);
38 System.out.println(path3);
39
40 // File toFile(): 将Path转化为File类的对象
41 File file = path1.toFile();//Path--->File的转换
42
43 Path newPath = file.toPath();//File--->Path的转换
44
45 }
3、Files 常用方法
1 @Test 2 public void test1() throws IOException{ 3 Path path1 = Paths.get("d:\\nio", "hello.txt"); 4 Path path2 = Paths.get("atguigu.txt"); 5 6 // Path copy(Path src, Path dest, CopyOption … how) : 文件的复制 7 //要想复制成功,要求path1对应的物理上的文件存在。path1对应的文件没有要求。 8 // Files.copy(path1, path2, StandardCopyOption.REPLACE_EXISTING); 9 10 // Path createDirectory(Path path, FileAttribute<?> … attr) : 创建一个目录 11 //要想执行成功,要求path对应的物理上的文件目录不存在。一旦存在,抛出异常。 12 Path path3 = Paths.get("d:\\nio\\nio1"); 13 // Files.createDirectory(path3); 14 15 // Path createFile(Path path, FileAttribute<?> … arr) : 创建一个文件 16 //要想执行成功,要求path对应的物理上的文件不存在。一旦存在,抛出异常。 17 Path path4 = Paths.get("d:\\nio\\hi.txt"); 18 // Files.createFile(path4); 19 20 // void delete(Path path) : 删除一个文件/目录,如果不存在,执行报错 21 // Files.delete(path4); 22 23 // void deleteIfExists(Path path) : Path对应的文件/目录如果存在,执行删除.如果不存在,正常执行结束 24 Files.deleteIfExists(path3); 25 26 // Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置 27 //要想执行成功,src对应的物理上的文件需要存在,dest对应的文件没有要求。 28 // Files.move(path1, path2, StandardCopyOption.ATOMIC_MOVE); 29 30 // long size(Path path) : 返回 path 指定文件的大小 31 long size = Files.size(path2); 32 System.out.println(size); 33 34 }
4、Files 常用方法2
1 @Test 2 public void test2() throws IOException{ 3 Path path1 = Paths.get("d:\\nio", "hello.txt"); 4 Path path2 = Paths.get("atguigu.txt"); 5 // boolean exists(Path path, LinkOption … opts) : 判断文件是否存在 6 System.out.println(Files.exists(path2, LinkOption.NOFOLLOW_LINKS)); 7 8 // boolean isDirectory(Path path, LinkOption … opts) : 判断是否是目录 9 //不要求此path对应的物理文件存在。 10 System.out.println(Files.isDirectory(path1, LinkOption.NOFOLLOW_LINKS)); 11 12 // boolean isRegularFile(Path path, LinkOption … opts) : 判断是否是文件 13 14 // boolean isHidden(Path path) : 判断是否是隐藏文件 15 //要求此path对应的物理上的文件需要存在。才可判断是否隐藏。否则,抛异常。 16 // System.out.println(Files.isHidden(path1)); 17 18 // boolean isReadable(Path path) : 判断文件是否可读 19 System.out.println(Files.isReadable(path1)); 20 // boolean isWritable(Path path) : 判断文件是否可写 21 System.out.println(Files.isWritable(path1)); 22 // boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在 23 System.out.println(Files.notExists(path1, LinkOption.NOFOLLOW_LINKS)); 24 }
5、Files 常用方法3
StandardOpenOption.READ:表示对应的Channel是可读的。
StandardOpenOption.WRITE:表示对应的Channel是可写的。
StandardOpenOption.CREATE:如果要写出的文件不存在,则创建。如果存在,忽略
StandardOpenOption.CREATE_NEW:如果要写出的文件不存在,则创建。如果存在,抛异常
1 @Test
2 public void test3() throws IOException{
3 Path path1 = Paths.get("d:\\nio", "hello.txt");
4
5 // InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
6 InputStream inputStream = Files.newInputStream(path1, StandardOpenOption.READ);
7
8 // OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象
9 OutputStream outputStream = Files.newOutputStream(path1, StandardOpenOption.WRITE,StandardOpenOption.CREATE);
10
11
12 // SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接,how 指定打开方式。
13 SeekableByteChannel channel = Files.newByteChannel(path1, StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE);
14
15 // DirectoryStream<Path> newDirectoryStream(Path path) : 打开 path 指定的目录
16 Path path2 = Paths.get("e:\\teach");
17 DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path2);
18 Iterator<Path> iterator = directoryStream.iterator();
19 while(iterator.hasNext()){
20 System.out.println(iterator.next());
21 }
22
23
24 }
七、
八、