java NIO2(file io)

简介:
Technorati 标签:  java, nio2

一、Path 类

    从 java 7 开始引进了一个类 Path,可以想当然地认为这个类就是为操作路径而诞生的。Path 对象包含了其对应的文件名和目录列表,可以用来检索、定位和操作文件。

    1、创建一个Path 对象

    可以使用辅助类辅助类 Paths.get()方法获取一个 Path 对象(注意辅助类是 Path),Demo:

Path p1 = Paths.get("/tmp/foo");
Path p2 = Paths.get(filename);
Path p3 = Paths.get(URI.create("C://File.java"));

    方法 Paths.get()可以看成下面的缩写:

    Path path = FileSystems.getDefault().getPath("C:\\File.java");

    2、提取 Path 对象的信息

Path path = Paths.get("D:\\Program Files\\Java\\text.txt");
 
System.out.format("toString: %s%n", path.toString());        //D:\Program Files\Java\text.txt
System.out.format("getFileName: %s%n", path.getFileName());    //text.txt
System.out.format("getName(0): %s%n", path.getName(0));        //Program Files
System.out.format("getNameCount: %d%n", path.getNameCount());    //3
System.out.format("subpath(0,2): %s%n", path.subpath(0,2));    // Program Files\Java
System.out.format("getParent: %s%n", path.getParent());        // D:\Program Files\Java
System.out.format("getRoot: %s%n", path.getRoot());            //D:\

    Path 同样可以是想对象路劲,如下:

    Path path = Paths.get(“\\java\\text.txt”);

    3、Path 的转换

    (1)将 path 转换为 uri,使用Path.toUri() 方法,如下:

Path path = Paths.get("\\Java\\text.txt");
System.out.format("%s%n", path.toUri());
//输出:file:///I:/Java/text.txt

    (2)toAbsolutePath 转换为绝对路径,如下:

Path path = Paths.get("\\Java\\text.txt");
System.out.format("%s%n", path.toAbsolutePath());
//输出:I:\Java\text.txt

    (3)toFile() 转换为文件,如下:

Path path = Paths.get("D:\\Program Files\\Java\\text.txt");
File filePath = path.toFile();
System.out.format("%s%n",filePath);
System.out.format("fileExist? %b%n",filePath.exists());
//输出:D:\Program Files\Java\text.txt
//fileExist? true

   4、连接两个 path

    (1)当被连接的 path 不包含的根路径时,会直接将此 path 连接到原 path 后面,如下:

Path path = Paths.get("D:\\Program Files\\Java");
System.out.format("%s%n",path.resolve("other.txt"));
//输出:D:\Program Files\Java\other.txt
//注意:这里并没有创建 other.txt这个文件

    (2)当被连接的 path 包含根路径时,resolve()h会返回此 path 对象,如下:

Path path = Paths.get("java").resolve("D:\\Program Files");
System.out.format("%s%n",path);
//输出:D:\Program Files

   5、在两个 path 之间创建它们的路径

    有时候我们需要知道两个文件夹之间的路径,如下:

Path p1 = Paths.get("jdk1.7.0_40");
Path p2 = Paths.get("java");
Path p1_to_p2 = p1.relativize(p2);//..\java
Path p2_to_p1 = p1_to_p2.relativize(p1);//..\..\jdk1.7.0_40

    6、比较两个 path

    Path 对象支持使用 equals()方法来判断两个path 是否一致,也可以使用 startWith() 和 endWith() 来判断path 是否以 指定字符串开始或结束。如下:

Path path = ...;
Path otherPath = ...;
Path beginning = Paths.get("/home");
Path ending = Paths.get("java");
 
if (path.equals(otherPath)) {
} else if (path.startsWith(beginning)) {
    // 以“/home”开始的path
} else if (path.endsWith(ending)) {
    // 以 “java” 结束的 path
}

二、文件操作

   当存在一个 path 对象时,需要判断这个 path 对应的文件(或目录)是否存在,是否可读,是否可写??

    ...

   1、判断文件/目录 是否存在

   可以使用方法 exists(Path, LinkOption...) 和 notExists(Path, LinkOption...) 来判断文件/目录是否存在。值得引起注意的一件事是,!Files.exist(path) 并与 Files.exist(path) 等同,因为当你在测试一个文件/目录是否存在时,有可能出现以下三种结果:

    (1)文件/目录 确认存在

    (2)文件/目录 确认不存在

    (3)无法判断文件/目录是否存在,这种情况会出在在程序无权访问指定文件/目录 时。

    当 exists()和 notExists()都返回 false,无法判断指定文件/目录 是否存在。

    2、检查文件的访问权

    使用 isReadable(Path), isWritable(Path), 和 isExecutable(Path) 方法,可以判断出文件是否可以被访问。如下代码,判断文件是否可以执行:

Path file = ...;
boolean isRegularExecutableFile = Files.isRegularFile(file) & Files.isReadable(file) & Files.isExecutable(file);

    3、判断两个 path 是否为同一文件/目录

    使用 isSameFile(Path, Path) 判断是否为同一文件/目录,如下:

Path p1 = ...;
Path p2 = ...;
if (Files.isSameFile(p1, p2)) {
    ...
}

   4、删除 文件/目录

    (1)使用 delete(path)方法可以删除一个文件/目录,如果删除失败,会判处一个 IO 异常。如,当文件不存在时,会抛出 NoSuchFileException,如下:

try {
    Files.delete(path);
} catch (NoSuchFileException x) {
    System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
    System.err.format("%s not empty%n", path);
} catch (IOException x) {
    // 在此捕捉无权操作文件异常
    System.err.println(x);
}

    (2)使用 deleteIfExists(Path) 同样可以删除文件/目录,不过此方法不会抛出异常

    5、复制文件/目录

    可以使用方法 copy(Path, Path, CopyOption...) 复制一个文件/目录,除非指定了 REPLACE_EXISTING ,否则当目标文件已存在是,复制都会失败。

    另外当复制目录时,并不会复制其内的文件,换言之,无论被复制的目录里有多少文件,新复制出来的为目录都是空的。

    当复制一个快捷方式时,会复制这个快捷方式对应的文件。如果只是想复制快捷方式本事,可以指定 CopyOption 为 REPLACE_EXISTING  或者 NOFOLLOW_LINKS

    CopyOption 支持一下枚举变量:

    (1)REPLACE_EXISTING  复制和替换已存在的文件

    (2)COPY_ATTRIBUTES 将原文件的文件属性复制给目标文件。

    (3)NOFOLLOW_LINKS 只是复制快捷方式本身。

   如下演示了如何使用 copy(Path, Path, CopyOption...) :

import static java.nio.file.StandardCopyOption.*;
...
Files.copy(source, target, REPLACE_EXISTING);

    另外,在 Files 里,也定义其他方法,用来处理 流与文件 之间的复制。方法 copy(InputStream, Path, CopyOptions...) 可以将输入的任意的 字节流飞复制到一个文件里;方法 copy(Path, OutputStream) 可以将任意文件以字节的形式复制到一个输出流里。

   6、移动文件/目录

    可以使用方法 move(Path, Path, CopyOption...) 移动文件/目录,除非指定了 CopyOption 为 REPLACE_EXISTING ,否则当目标文件已存在时,移动失败。

    使用模板如下:

import static java.nio.file.StandardCopyOption.*;
...
Files.move(source, target, REPLACE_EXISTING);

    7、操作文件的属性

    因为不同的操作系统,支持的文件属性与操作方式不一致,在这里只是演示一下如何获取基本的文件属性。

public class FileIoTest {
    public static void main(String[] args) throws IOException {
 
        Path path = Paths.get("D:\\Program Files\\Java");
        BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
 
        System.out.println("creationTime: " + attr.creationTime());
        System.out.println("lastAccessTime: " + attr.lastAccessTime());
        System.out.println("lastModifiedTime: " + attr.lastModifiedTime());
 
        System.out.println("isDirectory: " + attr.isDirectory());
        System.out.println("isOther: " + attr.isOther());
        System.out.println("isRegularFile: " + attr.isRegularFile());
        System.out.println("isSymbolicLink: " + attr.isSymbolicLink());
        System.out.println("size: " + attr.size());
        
    }
}


 
 
相关文章
|
8天前
|
Java Unix Windows
|
1天前
|
存储 Java
Java的`java.io`包包含多种输入输出类
Java的`java.io`包包含多种输入输出类。此示例展示如何使用`FileInputStream`从`input.txt`读取数据。首先创建`FileInputStream`对象,接着分配一个`byte`数组存储流中的数据。通过`read()`方法读取数据,然后将字节数组转换为字符串打印。最后关闭输入流释放资源。`InputStream`是抽象类,此处使用其子类`FileInputStream`。其他子类如`ByteArrayInputStream`、`ObjectInputStream`和`BufferedInputStream`各有特定用途。
7 1
|
2天前
|
存储 Java
java IO接口(Input)用法
【5月更文挑战第1天】Java的`java.io`包包含多种输入输出类。此示例展示了如何使用`FileInputStream`从`input.txt`读取数据。首先创建`FileInputStream`对象,接着创建一个字节数组存储读取的数据,调用`read()`方法将文件内容填充至数组。然后将字节数组转换为字符串并打印,最后关闭输入流。注意,`InputStream`是抽象类,此处使用其子类`FileInputStream`。其他子类如`ByteArrayInputStream`、`ObjectInputStream`和`BufferedInputStream`各有特定用途。
12 2
|
4天前
|
存储 Java Linux
【Java EE】 文件IO的使用以及流操作
【Java EE】 文件IO的使用以及流操作
|
5天前
|
存储 Java 测试技术
Java基础IO总结(下)
Java基础IO总结(下)
11 0
|
5天前
|
存储 Java
Java基础IO总结(上)
Java基础IO总结(上)
10 0
|
7天前
|
网络协议 Java Linux
Java基础BIO、NIO、AIO小结(下)
Java基础BIO、NIO、AIO小结(下)
14 0
|
7天前
|
缓存 Java 测试技术
Java基础BIO、NIO、AIO小结(上)
Java基础BIO、NIO、AIO小结
16 0
|
9天前
|
存储 Java 数据库
[Java 基础面试题] IO相关
[Java 基础面试题] IO相关
|
9天前
|
缓存 Java API
Java NIO和IO之间的区别
NIO(New IO),这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
14 1