Java从java.io.File迁移到Java 7 NIO(java.nio.file.Path)

示例

这些示例假设您已经知道Java 7的NIO通常是什么,并且习惯于使用编写代码java.io.File。使用这些示例作为快速查找更多以NIO为中心的文档进行迁移的方法。

Java 7的NIO还有更多功能,例如内存映射文件或使用FileSystem打开ZIP或JAR文件。这些示例将仅涵盖有限数量的基本用例。

作为基本规则,如果习惯于使用java.io.File实例方法执行文件系统的读/写操作,您将在中找到它作为静态方法java.nio.file.Files。

指向路径

// -> IO
File file = new File("io.txt");

// -> NIO
Path path = Paths.get("nio.txt");

相对于另一条路径的路径

// 即使在Windows操作系统上,也可以使用正斜杠代替反斜杠
// -> IO
File folder = new File("C:/");
File fileInFolder = new File(folder, "io.txt");

// -> NIO
Path directory = Paths.get("C:/");
Path pathInDirectory = directory.resolve("nio.txt");

从文件到路径转换文件以与库一起使用

// -> IO to NIO
Path pathFromFile = new File("io.txt").toPath();

// -> NIO to IO
File fileFromPath = Paths.get("nio.txt").toFile();

检查文件是否存在,如果存在则将其删除

// -> IO
if (file.exists()) {
    boolean deleted = file.delete();
    if (!deleted) {
        throw new IOException("Unable to delete file");
    }
}

// -> NIO
Files.deleteIfExists(path);

通过OutputStream写入文件

对于不同的性能和内存限制,可读性和用例,有多种方法可以使用NIO进行文件读写FileChannel,Files.write(Path path, byte\[\] bytes, OpenOption... options)在此示例中,仅OutputStream进行介绍,但是强烈建议您学习有关内存映射的知识文件和可用的各种静态方法java.nio.file.Files。

List<String> lines = Arrays.asList(
        String.valueOf(Calendar.getInstance().getTimeInMillis()),
        "line one",
        "line two");

// -> IO
if (file.exists()) {
    // 注意:不是原子的
    throw new IOException("File already exists");
}
try (FileOutputStream outputStream = new FileOutputStream(file)) {
    for (String line : lines) {
        outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
    }
}

// -> NIO
try (OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW)) {
    for (String line : lines) {
        outputStream.write((line + System.lineSeparator()).getBytes(StandardCharsets.UTF_8));
    }
}

遍历文件夹中的每个文件

// -> IO
for (File selectedFile : folder.listFiles()) {
    // 注意:根据目录文件夹中的文件数,listFiles()可能需要很长时间才能返回
    System.out.println((selectedFile.isDirectory() ? "d" : "f") + " " + selectedFile.getAbsolutePath());
}

// -> NIO
Files.walkFileTree(directory, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path selectedPath, BasicFileAttributes attrs) throws IOException {
        System.out.println("d " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws IOException {
        System.out.println("f " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }
});

递归文件夹迭代

// -> IO
recurseFolder(folder);

// -> NIO
// 注意:除非明确将其作为参数传递给Files.walkFileTree,否则不遵循符号链接。
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        System.out.println("d " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path selectedPath, BasicFileAttributes attrs) throws IOException {
        System.out.println("f " + selectedPath.toAbsolutePath());
        return FileVisitResult.CONTINUE;
    }
});


private static void recurseFolder(File folder) {
    for (File selectedFile : folder.listFiles()) {
        System.out.println((selectedFile.isDirectory() ? "d" : "f") + " " + selectedFile.getAbsolutePath());
        if (selectedFile.isDirectory()) {
            // 注意:遵循符号链接
            recurseFolder(selectedFile);
        }
    }
}