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());
        
    }
}


 
 
相关文章
|
1月前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
44 3
|
1月前
|
存储 监控 Java
Java的NIO体系
通过本文的介绍,希望您能够深入理解Java NIO体系的核心组件、工作原理及其在高性能应用中的实际应用,并能够在实际开发中灵活运用这些知识,构建高效的Java应用程序。
46 5
|
2月前
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
64 9
|
3月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
111 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
消息中间件 缓存 Java
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
零拷贝技术 Zero-Copy 是指计算机执行操作时,可以直接从源(如文件或网络套接字)将数据传输到目标缓冲区, 而不需要 CPU 先将数据从某处内存复制到另一个特定区域,从而减少上下文切换以及 CPU 的拷贝时间。
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
|
2月前
|
Java 编译器 Maven
Java“class file contains wrong class”解决
当Java程序运行时出现“class file contains wrong class”错误,通常是因为类文件与预期的类名不匹配。解决方法包括:1. 确保类名和文件名一致;2. 清理并重新编译项目;3. 检查包声明是否正确。
75 3
|
4月前
|
存储 Java
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
这篇文章介绍了Java中ObjectInputStream和ObjectOutputStream类的基本使用,这两个类用于实现对象的序列化和反序列化。文章解释了序列化的概念、如何通过实现Serializable接口来实现序列化,以及如何使用transient关键字标记不需要序列化的属性。接着,通过示例代码演示了如何使用ObjectOutputStream进行对象的序列化和ObjectInputStream进行反序列化。
序列化流 ObjectInputStream 和 ObjectOutputStream 的基本使用【 File类+IO流知识回顾④】
|
3月前
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
53 2
|
3月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
55 1
|
3月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
131 1