349. Java IO API - Java 文件操作:java.io.File 与 java.nio.file 功能对比 - 1

0 阅读2分钟

349. Java IO API - 逐步迁移到 java.nio.file API - 1

如果望充分利用 java.nio.file 包提供的强大功能,可以通过 File.toPath() 方法将旧代码逐步迁移到新的 Path 接口。但如果不想使用这种方法,或者需要对文件 I/O 代码进行重写,将不得不重构代码以完全使用新的 Path API。

Java 文件操作:java.io.Filejava.nio.file 功能对比

在 Java 编程里,文件操作是一项常见的任务。Java 提供了两个主要的文件操作 API:java.io.Filejava.nio.file。前者是 Java 早期就有的 API,而后者是 Java 7 引入的新 API,具备更强大的功能和更好的性能。接下来,我们会对这两个 API 的功能进行对比,同时给出示例代码辅助理解。

1. 路径表示
  • java.io.File:使用 java.io.File 类来表示文件或目录的路径。
  • java.nio.file.Path:使用 java.nio.file.Path 接口来表示文件或目录的路径,它更为灵活和强大。

示例代码

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathExample {
    public static void main(String[] args) {
        // 使用 java.io.File
        File file = new File("test.txt");
        System.out.println("java.io.File: " + file);

        // 使用 java.nio.file.Path
        Path path = Paths.get("test.txt");
        System.out.println("java.nio.file.Path: " + path);
    }
}
2. 随机访问文件
  • java.io.RandomAccessFile:可以随机访问文件的内容。
  • java.nio.file.SeekableByteChanneljava.nio.file 包中的 SeekableByteChannel 接口也能实现随机访问文件的功能。

示例代码

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class RandomAccessExample {
    public static void main(String[] args) throws IOException {
        // 使用 java.io.RandomAccessFile
        RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
        raf.writeBytes("Hello, World!");
        raf.seek(0);
        byte[] buffer = new byte[13];
        raf.read(buffer);
        System.out.println("java.io.RandomAccessFile: " + new String(buffer));
        raf.close();

        // 使用 java.nio.file.SeekableByteChannel
        Path path = Paths.get("test.txt");
        SeekableByteChannel sbc = Files.newByteChannel(path);
        ByteBuffer bb = ByteBuffer.allocate(13);
        sbc.read(bb);
        bb.flip();
        System.out.println("java.nio.file.SeekableByteChannel: " + new String(bb.array()));
        sbc.close();
    }
}
3. 文件权限检查
  • java.io.File:使用 File.canRead()File.canWrite()File.canExecute() 方法来检查文件的读写执行权限。
  • java.nio.file.Files:使用 Files.isReadable()Files.isWritable()Files.isExecutable() 方法来检查文件的读写执行权限。在 UNIX 文件系统中,还能借助 Managing Metadata (File and File Store Attributes) 包检查九种文件权限。

示例代码

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PermissionExample {
    public static void main(String[] args) throws IOException {
        // 使用 java.io.File
        File file = new File("test.txt");
        System.out.println("java.io.File - Readable: " + file.canRead());
        System.out.println("java.io.File - Writable: " + file.canWrite());
        System.out.println("java.io.File - Executable: " + file.canExecute());

        // 使用 java.nio.file.Files
        Path path = Paths.get("test.txt");
        System.out.println("java.nio.file.Files - Readable: " + Files.isReadable(path));
        System.out.println("java.nio.file.Files - Writable: " + Files.isWritable(path));
        System.out.println("java.nio.file.Files - Executable: " + Files.isExecutable(path));
    }
}
4. 文件元数据管理
  • java.io.File:使用 File.isDirectory()File.isFile()File.length()File.lastModified()File.setLastModified(long) 等方法来管理文件的元数据。
  • java.nio.file.Files:使用 Files.isDirectory(Path, LinkOption...)Files.isRegularFile(Path, LinkOption...)Files.size(Path)Files.getLastModifiedTime(Path, LinkOption...)Files.setLastModifiedTime(Path, FileTime) 等方法来管理文件的元数据。

示例代码

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.util.Date;

public class MetadataExample {
    public static void main(String[] args) throws IOException {
        // 使用 java.io.File
        File file = new File("test.txt");
        System.out.println("java.io.File - Is Directory: " + file.isDirectory());
        System.out.println("java.io.File - Is File: " + file.isFile());
        System.out.println("java.io.File - Length: " + file.length());
        System.out.println("java.io.File - Last Modified: " + new Date(file.lastModified()));
        file.setLastModified(System.currentTimeMillis());
        System.out.println("java.io.File - New Last Modified: " + new Date(file.lastModified()));

        // 使用 java.nio.file.Files
        Path path = Paths.get("test.txt");
        System.out.println("java.nio.file.Files - Is Directory: " + Files.isDirectory(path));
        System.out.println("java.nio.file.Files - Is Regular File: " + Files.isRegularFile(path));
        System.out.println("java.nio.file.Files - Size: " + Files.size(path));
        FileTime lastModifiedTime = Files.getLastModifiedTime(path);
        System.out.println("java.nio.file.Files - Last Modified: " + lastModifiedTime);
        Files.setLastModifiedTime(path, FileTime.fromMillis(System.currentTimeMillis()));
        lastModifiedTime = Files.getLastModifiedTime(path);
        System.out.println("java.nio.file.Files - New Last Modified: " + lastModifiedTime);
    }
}
5. 设置文件属性
  • java.io.File:使用 setExecutable()setReadable()setReadOnly()setWritable() 等方法来设置文件的属性。
  • java.nio.file.Files:使用 Files.setAttribute(Path, String, Object, LinkOption...) 方法来设置文件的属性。

示例代码

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class AttributeExample {
    public static void main(String[] args) throws IOException {
        // 使用 java.io.File
        File file = new File("test.txt");
        file.setExecutable(false);
        file.setReadable(true);
        file.setWritable(true);

        // 使用 java.nio.file.Files
        Path path = Paths.get("test.txt");
        Files.setAttribute(path, "dos:readonly", false);
    }
}

总结

java.nio.file 包是 Java 7 引入的新文件操作 API,相较于 java.io.File 具有更强大的功能和更好的性能。在实际开发中,建议优先使用 java.nio.file 包进行文件操作。