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