Java文件 – java.nio.file.Files类

Java Files类是在Java 1.7中引入的,是java.nio.file包的一部分。

Java Files类

  • Java Files类包含一些静态方法,用于处理文件和目录。
  • 这个类用于基本的文件操作,如创建、读取、写入、复制和删除文件或目录。

在继续之前,让我们首先看一下以下术语:

  1. Path:这是一个接口,用于在Java NIO中处理文件或目录时替代java.io.File类。
  2. Paths:这个类包含一个静态方法来创建Path实例。

java.nio.file.Path 接口 就像旧的 java.io.File 类一样。 Path 表示文件的位置,当我们创建一个指向新文件的路径时,它不会创建实际的文件,直到我们使用 Files.createFile(Path filePath) 创建它。 如上图所示,Paths 类用于创建 Path 实例,而 Files 类使用 Path 实例来处理文件。 FilePath 对象知道如何相互转换,这就是我们可以使用旧代码与新的 Files 工具进行交互的方式。

Java IO vs NIO

如何创建 Path

我们可以通过调用 Paths.get(String first, String... more) 方法来创建 Path 对象,该方法属于 Paths 类。

Path path1 = Paths.get("/tmp/file.txt"); // For UNIX

Path path2 = Paths.get("D:/data/file.txt"); // For Windows

我们还可以通过在 Paths.get() 方法中分隔路径的各个部分来创建 Path 对象。

Path path1 = Paths.get("/tmp", "file.txt");

Path path2 = Paths.get("D:", "data", "file.txt");

Path path3 = Paths.get("D:/data", "file.txt") ;

正如我们所看到的,我们可以在 Paths.get() 方法中分别传递文件夹和文件名。

Java文件方法

Java NIO Files类包含一些静态方法,用于操作文件和目录,这些方法大多作用于Path对象。让我们来看看Files类的以下方法:

  1. copy(InputStream in, Path target, CopyOption… options):该方法将指定输入流的所有字节复制到指定的目标文件,并返回读取或写入的字节数,返回类型为long值。
  2. copy(Path source, OutputStream out):该方法将指定源文件的所有字节复制到给定的输出流,并返回读取或写入的字节数,返回类型为long值。
  3. copy(Path source, Path target, CopyOption… options):该方法将给定的源文件复制到指定的目标文件,并返回目标文件的路径。
  4. createDirectories(Path dir, FileAttribute<?>… attrs):该方法使用给定的路径创建目录,首先创建所有不存在的父目录。如果目录已经存在,该方法不会抛出异常。FileAttribute是一个可选参数,用于在创建不存在的目录时自动设置,它返回创建的目录的路径。
  5. createDirectory(Path dir, FileAttribute<?>… attrs): 此方法使用给定的路径创建目录,如果成功创建目录,则返回已创建目录的路径。如果目录已经存在,则会抛出 nio.file.FileAlreadyExistsException。
  6. createFile(Path path, FileAttribute<?>… attrs): 此方法使用给定的路径创建一个新的空文件,并返回新创建文件的路径(如果成功创建)。如果文件已经存在,则会抛出 nio.file.FileAlreadyExistsException。
  7. createTempDirectory(Path dir, String prefix, FileAttribute<?>… attrs): 此方法使用给定的路径创建一个临时目录,并使用给定的前缀生成目录名称。它将返回新创建临时目录的路径。
  8. createTempDirectory(String prefix, FileAttribute<?>… attrs): 此方法在默认临时文件目录中创建一个临时目录,并使用给定的前缀生成目录名称。它将返回与默认文件系统关联的新创建临时目录的路径。
  9. createTempFile(Path dir, String prefix, String suffix, FileAttribute<?>… attrs): 此方法在指定目录创建临时文件,并使用给定的前缀和后缀生成文件名,并返回新创建文件的路径。
  10. createTempFile(String prefix, String suffix, FileAttribute<?>… attrs): 该方法在默认临时文件目录创建一个临时文件,使用给定的前缀和后缀生成文件名,并返回新创建文件的路径。
  11. delete(Path path): 这是一个无返回值的方法,简单地从指定路径删除文件。如果文件不存在于指定路径,则该方法会抛出NoSuchFileException,如果文件是目录并且可能不为空且无法删除,则会抛出
  12. deleteIfExists(Path path): 在删除文件之前,此方法检查文件是否存在,并在成功删除给定路径的文件时返回布尔值true,如果文件在给定路径不存在,则返回false。如果文件是目录并且可能不为空且无法删除,则会抛出
  13. exists(Path path): 此方法检查指定路径的文件是否存在,如果文件存在,则返回true,否则返回false。
  14. getLastModifiedTime(Path path, Linkoption… options): 该方法从给定路径返回文件的最后修改时间为
  15. getOwner(Path path, Linkoption… options): 此方法返回表示给定路径上文件所有者的UserPrincipal
  16. isDirectory(Path path, LinkOption… options): 该方法检查给定路径的文件是否为目录。如果文件是目录,则返回true;如果文件不存在、不是目录,或无法确定文件是否为目录,则返回false。
  17. isExecutable(Path path): 该方法检查给定路径处的文件是否可执行,并检查文件是否存在以及此JVM是否具有执行文件的适当权限。如果文件在给定路径存在且可执行,则返回true;如果文件不存在、JVM没有足够的权限执行文件或无法确定访问权限,则返回false。
  18. isHidden(Path path): 该方法判断给定路径处的文件是否被视为隐藏。“隐藏”的确切定义取决于平台或提供程序。在UNIX系统中,如果文件名以句点字符(’.’)开头,则该文件被视为隐藏;在WINDOWS中,如果文件不是目录且设置了DOS隐藏属性,则该文件被视为隐藏。如果给定路径处的文件被视为隐藏,则返回true;否则返回false。
  19. isReadable(Path path): 该方法测试给定路径处的文件是否可读。如果指定路径处的文件存在且可读,则返回true;如果文件不存在、读取访问被拒绝因为JVM没有足够的权限或无法确定访问权限,则返回false。
  20. isWritable(Path path):此方法测试给定路径处的文件是否可写。如果指定路径处的文件存在且可写,则返回true;如果文件不存在,或因JVM权限不足而拒绝写入访问,或无法确定访问权限,则返回false。
  21. move(Path source, Path target, CopyOption… options):此方法将源文件移动或重命名为目标文件,并返回目标文件的路径。选项参数可能包括以下内容:REPLACE_EXISTING:如果目标文件存在,则替换它,如果目标文件是非空目录,则不替换。ATOMIC_MOVE:执行移动作为原子文件系统操作,并忽略所有其他选项。如果目标文件存在但无法替换,因为未指定REPLACE_EXISTING选项,则抛出FileAleadyExistsException。如果指定了REPLACE_EXISTING选项但无法替换文件,因为它是非空目录,则抛出DirectoryNotEmptyException
  22. newBufferedReader(Path path, Charset cs):此方法使用给定的路径打开文件以供读取,返回一个BufferedReader,用于从文件中读取文本。文件中的字节将使用指定的字符集解码为字符。
  23. newBufferedWriter(Path path, Charset cs, OpenOption… options): 该方法通过给定的路径打开或创建文件,返回一个用于向文件写入文本的BufferedWriter。options参数指定文件的创建或打开方式。如果未指定任何选项,则默认为CREATE, TRUNCATE_EXISTINGWRITE选项,这意味着它将打开文件进行写入,如果文件不存在,则创建新文件,如果文件存在,则截断文件大小为0。如果指定了不受支持的选项,则该方法抛出UnsupportedOperationException异常。
  24. newByteChannel(Path path, OpenOption… options): 该方法通过指定的路径创建或打开文件,返回一个可寻址的字节通道,用于访问文件。如果指定了不受支持的选项,则该方法抛出UnsupportedOperationException异常。
  25. newDirectoryStream(Path path): 该方法通过指定的路径打开一个目录,返回一个DirectoryStream,用于迭代目录中所有条目。DirectoryStream的迭代器返回的元素是Path类型,每个元素表示目录中的一个条目。如果无法打开给定路径处的文件,因为它不是目录,则该方法抛出NotDirectoryException异常。
  26. newDirectoryStream(Path path, Filter<? super Path > filter): 此方法通过返回 DirectoryStream 打开目录,以便从指定路径遍历目录中的所有条目。DirectoryStream 迭代器返回的元素类型为 Path,每个 Path 代表目录中的一个条目,这些条目由指定的过滤器进行过滤。如果由于指定的路径不是目录而无法打开该路径上的文件,则此方法会抛出 NotDirectoryException
  27. newDirectoryStream(Path path, String glob): 此方法通过返回 DirectoryStream 打开目录,以便从指定路径遍历目录中的所有条目。DirectoryStream 迭代器返回的元素类型为 Path,每个 Path 代表目录中的一个条目,这些条目通过与指定的 glob 模式匹配其文件名的字符串表示进行过滤。如果由于指定的路径不是目录而无法打开该路径上的文件,则此方法会抛出 NotDirectoryException,如果模式无效,则会抛出 PatternSyntaxException
  28. newInputStream(Path path, Openoption… options): 此方法通过返回输入流打开文件,以便从指定路径读取文件。options 参数确定如何打开文件,如果未指定选项,则使用 READ 打开文件。如果指定了无效的选项组合,则此方法会抛出 IllegalArgumentException,如果指定了不受支持的选项,则会抛出 UnsupportedOperationException
  29. newOutputStream(Path path, OpenOption… options): 该方法通过返回输出流打开文件,以便将字节写入指定路径的文件。options参数用于确定如何打开文件,如果未指定选项,则默认考虑CREATE,TRUNCATE_EXISTINGWRITE选项,这意味着它以写入模式打开文件,如果文件不存在,则创建文件,如果存在,则将其截断为0大小。如果指定了无效的选项组合,则此方法抛出IllegalArgumentException,如果指定了不受支持的选项,则抛出UnsupportedOperationException
  30. notExists(Path path, LinkOption options): 该方法测试指定路径的文件是否不存在。options参数用于指示如何处理文件符号链接。默认情况下,会遵循符号链接。如果存在NOFOLLOW_LINK选项,则不会遵循符号链接。如果文件在指定路径不存在,则此方法返回true,如果文件存在或其存在无法确定,则返回false。
  31. readAllBytes(Path path): 该方法从给定路径的文件中读取所有字节,并返回包含从文件中读取的字节的字节数组。
  32. readAllLines(Path path, Charset cs): 该方法从给定路径的文件中读取所有行,并返回包含文件行的List
  33. size(Path path): 该方法返回指定路径文件的大小,单位为字节。
  34. walkFileTree(Path start, FileVisitor<? Super Path> visitor): 该方法用于递归地遍历目录。它递归地遍历指定路径的目录并返回起始文件。
  35. write(Path path, byte[] bytes, OpenOption… options): 该方法将字节写入指定路径的文件。选项参数指定文件的创建或打开方式。如果未指定选项,则默认考虑CREATE, TRUNCATE_EXISTINGWRITE选项,这意味着它以写入方式打开文件,并在文件不存在时创建文件,或者如果存在则截断现有文件大小为0。将字节数组中的所有字节写入文件。该方法确保在写入所有字节后关闭文件,并返回写入文件的路径。

使用Files类创建文件

Files类提供createFile(Path filePath, FileAttribute<?>… attrs)方法,用于使用指定的Path创建文件。让我们看一下下面的示例程序。

package com.journaldev.examples;

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

/**
 * Java Create file using Files class
 * 
 * @author pankaj
 *
 */
public class FilesCreateFileExample {

	public static void main(String[] args) {
		
		//初始化Path对象
		Path path = Paths.get("D:/data/file.txt");
		//创建文件
		try {
			Path createdFilePath = Files.createFile(path);
			System.out.println("File Created at Path : "+createdFilePath);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

上述程序的输出如下:

File Created at Path : D:\data\file.txt

使用Files类创建目录

Files类提供了createDirectory(Path dir, FileAttribute<?>… attrs)createDirectories(Path dir, FileAttribute<?>… attrs)方法,用于使用指定的Path创建单个和多级目录。让我们看下面的示例程序。

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Java Create directories using Files class
 * 
 * @author pankaj
 *
 */
public class FilesCreateDirectoriesExample {

	public static void main(String[] args) {
		// 初始化Path对象
		Path path1 = Paths.get("D:/pankaj");
		Path path2 = Paths.get("D:/pankaj/java7");
		Path path3 = Paths.get("D:/pankaj/java7/Files");
		
		try {
			Path createdDir1 = Files.createDirectory(path1);//first level directory
			Path createdDir2 = Files.createDirectory(path2);//second level directory
			Path createdDir3 = Files.createDirectory(path3);//all level directories
			System.out.println("First Level Directory Created at Path : "+createdDir1);
			System.out.println("Second Level Directory Created at Path : "+createdDir2);
			System.out.println("All Level Directories Created at Path : "+createdDir3);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

上述程序的输出如下:

First Level Directory Created at Path : D:\pankaj
Second Level Directory Created at Path : D:\pankaj\java7
All Level Directories Created at Path : D:\pankaj\java7\Files

将文件转换为路径,反之亦然

可以使用以下方法将File和Path对象相互转换:

File file = new File(“D:/data/file.txt”);

Path path = file.toPath();

File file1 = path.toFile();

使用Files类读取文件数据

Files类提供了以下用于读取文件的方法。

  1. readAllBytes(Path path):此方法从给定路径的文件中读取所有字节,并返回包含从文件中读取的字节的字节数组。
  2. readAllLines(Path path,Charsetcs): 此方法从给定路径的文件中读取所有行,并返回包含文件行的List

让我们看下面的示例程序。

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * Java Files read file example
 * 
 * @author pankaj
 *
 */
public class FilesReadFileExample {

	public static void main(String[] args) {
		
		Path path = Paths.get("D:/data/file.txt");
		try {
			byte[] bs = Files.readAllBytes(path);
			List<String> strings = Files.readAllLines(path);
			
			System.out.println("Read bytes: \n"+new String(bs));
			System.out.println("Read lines: \n"+strings);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

上述程序的输出如下:

Read bytes: 
Hello world
This is Read file example
Thank you
Read lines: 
[Hello world, This is Read file example, Thank you]

使用Files类复制文件

Files类提供了copy(Path source, Path target, CopyOption… options)方法,将给定的源文件复制到指定的目标文件,并返回目标文件的路径。让我们看下面的示例程序:

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * Java Files copy file example
 * 
 * @author pankaj
 *
 */
public class FilesCopyFileExample {

	public static void main(String[] args) {
		Path sourcePath = Paths.get("D:/data/sourceFile.txt");
		Path targetPath = Paths.get("D:/data/targetFile.txt");
		
		try {
			Path path = Files.copy(sourcePath, targetPath,StandardCopyOption.REPLACE_EXISTING);//copy with REPLACE_EXISTING option
			System.out.println("Target file Path : "+path);
			System.out.println("Copied Content : \n"+new String(Files.readAllBytes(path)));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

上述程序的输出如下:

Target file Path : D:\data\targetFile.txt
Copied Content : 
Hello world
This is Copy file example
Thank you

使用Files类移动文件

Java Files类提供了move(Path source, Path target, CopyOption… options)方法,该方法将源文件移动或重命名为目标文件,并返回目标文件的路径。选项参数可能包括以下内容:REPLACE_EXISTING:如果目标文件存在,则替换它,如果它不是一个非空目录。ATOMIC_MOVE:表示移动操作作为原子文件系统操作执行,所有其他选项将被忽略。如果目标文件存在但不能被替换,因为未指定REPLACE_EXISTING选项,则该方法会抛出FileAleadyExistsException。如果指定了REPlACE_EXISTING选项但无法替换文件,因为它是一个非空目录,则该方法会抛出DirectoryNotEmptyException。让我们看下面的示例程序:

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

/**
 * Java Files move file example
 * 
 * @author pankaj
 *
 */
public class FilesMoveFileExample {

	public static void main(String[] args) {
		Path sourcePath = Paths.get("D:/data/sourceFile.txt");
		Path targetPath = Paths.get("D:/data/targetFile.txt");
		try {
			Path path = Files.move(sourcePath, targetPath,StandardCopyOption.REPLACE_EXISTING);//move with REPLACE_EXISTING option
			System.out.println("Target file Path : "+path);
			System.out.println("Moved Content : \n"+new String(Files.readAllBytes(path)));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

使用Files类编写文件

Java NIO Files 类提供了write(Path path, byte[] bytes, OpenOption… options) 方法,用于将字节写入指定路径的文件。选项参数指定了文件的创建或打开方式。如果未指定任何选项,则默认考虑CREATE, TRUNCATE_EXISTINGWRITE 选项。这意味着它打开文件进行写入,并在文件不存在时创建文件,或者如果文件存在则将其截断为0大小。将字节数组中的所有字节写入文件。该方法确保在所有字节被写入后关闭文件,并返回写入文件的路径。

package com.journaldev.examples;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Java Files write file example
 * 
 * @author pankaj
 *
 */
public class FilesWriteFileExample {

	public static void main(String[] args) {
		Path path = Paths.get("D:/data/test.txt");
		try {
			String str = "This is write file Example";
			byte[] bs = str.getBytes();
			Path writtenFilePath = Files.write(path, bs);
			System.out.println("Written content in file:\n"+ new String(Files.readAllBytes(writtenFilePath)));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

遍历文件树

Files 类提供了walkFileTree(Path start, FileVisitor<? Super Path> visitor) 方法,用于遍历目录。它递归地遍历指定路径的目录,并返回起始文件。

package com.journaldev.examples;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;

/**
 * Java Files walk file tree example
 * 
 * @author pankaj
 *
 */
public class FilesWalkFileTreeExample {

	public static void main(String[] args) {
		Path path = Paths.get("D:/pankaj");
		try {
			Files.walkFileTree(path, new FileVisitor<Path>() {

				@Override
				public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
					System.out.println("Post Visit Directory: "+dir);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
					System.out.println("Pre Visit Directory: "+dir);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
					System.out.println("Visit File: "+file);
					return FileVisitResult.CONTINUE;
				}

				@Override
				public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
					System.out.println("Visit Failed File: "+file);
					return FileVisitResult.CONTINUE;
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

上述程序的输出如下:

Pre Visit Directory: D:\pankaj
Pre Visit Directory: D:\pankaj\java6
Pre Visit Directory: D:\pankaj\java6\Files
Visit File: D:\pankaj\java6\Files\file.txt.txt
Post Visit Directory: D:\pankaj\java6\Files
Post Visit Directory: D:\pankaj\java6
Pre Visit Directory: D:\pankaj\java7
Pre Visit Directory: D:\pankaj\java7\Files
Visit File: D:\pankaj\java7\Files\file.txt.txt
Post Visit Directory: D:\pankaj\java7\Files
Post Visit Directory: D:\pankaj\java7
Pre Visit Directory: D:\pankaj\java8
Pre Visit Directory: D:\pankaj\java8\Files
Visit File: D:\pankaj\java8\Files\file.txt.txt
Post Visit Directory: D:\pankaj\java8\Files
Post Visit Directory: D:\pankaj\java8
Post Visit Directory: D:\pankaj

请注意,所有文件和文件夹都被递归处理。当您想对所有文件执行一些常见处理时,例如递归地重命名目录中的所有文件时,这非常有用。关于 Java Files 类就介绍到这里。参考:API 文档

Source:
https://www.digitalocean.com/community/tutorials/java-files-nio-files-class