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


 
 
相关文章
|
5月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
448 6
|
5月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
244 1
|
7月前
|
Java 测试技术 API
Java IO流(二):文件操作与NIO入门
本文详解Java NIO与传统IO的区别与优势,涵盖Path、Files类、Channel、Buffer、Selector等核心概念,深入讲解文件操作、目录遍历、NIO实战及性能优化技巧,适合处理大文件与高并发场景,助力高效IO编程与面试准备。
|
7月前
|
SQL Java 数据库连接
Java IO流(一):字节流与字符流基础
本文全面解析Java IO流,涵盖字节流、字符流及其使用场景,帮助开发者理解IO流分类与用途,掌握文件读写、编码转换、异常处理等核心技术,通过实战案例提升IO编程能力。
|
8月前
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
171 2
|
8月前
|
监控 Java API
现代 Java IO 高性能实践从原理到落地的高效实现路径与实战指南
本文深入解析现代Java高性能IO实践,涵盖异步非阻塞IO、操作系统优化、大文件处理、响应式网络编程与数据库访问,结合Netty、Reactor等技术落地高并发应用,助力构建高效可扩展的IO系统。
235 0
|
9月前
|
Linux C语言 网络架构
Linux的基础IO内容补充-FILE
而当我们将运行结果重定向到log.txt文件时,数据的刷新策略就变为了全缓冲,此时我们使用printf和fwrite函数打印的数据都打印到了C语言自带的缓冲区当中,之后当我们使用fork函数创建子进程时,由于进程间具有独立性,而之后当父进程或是子进程对要刷新缓冲区内容时,本质就是对父子进程共享的数据进行了修改,此时就需要对数据进行写时拷贝,至此缓冲区当中的数据就变成了两份,一份父进程的,一份子进程的,所以重定向到log.txt文件当中printf和fwrite函数打印的数据就有两份。此时我们就可以知道,
199 0
|
12月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
522 23
|
Java
java读写file
private static String encoding = "utf-8"; public static void readTxt(String filePath) throws IOException { File file = new File(filePath); if (file.
865 0