Java 是否有更好的方法替代File.listFiles()方法?
我需要读取目录中文件的绝对路径、文件名和大小。 我现在就是这样做的:Java 是否有更好的方法替代File.listFiles()方法?,java,performance,file,io,Java,Performance,File,Io,我需要读取目录中文件的绝对路径、文件名和大小。 我现在就是这样做的: File diretory = <dir_path>; File[] listFiles = directory.listFiles(); for (int i = 0; i < listFiles.length; i++) { String fileName = file.getName(); String filePath = file.getAbsolutePath(); lon
File diretory = <dir_path>;
File[] listFiles = directory.listFiles();
for (int i = 0; i < listFiles.length; i++) {
String fileName = file.getName();
String filePath = file.getAbsolutePath();
long fileLen = file.length();
long filelastModified = file.getLastModified();
...
}
文件目录=;
File[]listFiles=directory.listFiles();
对于(int i=0;i
我的目录中可以有1000个文件。由于I/O操作非常昂贵,这是完成我正在做的事情的最佳方式吗?AFAIK,这在Java中几乎是尽可能高效的。您可能可以压缩2%到5%,但这通常不是值得改进的性能 问题在于,典型的操作系统不提供一种方法来一次检索多个文件的元数据,或者一次检索多个元数据值 我希望元数据操作(
length()
,getLastModified()
等等)将占用绝大多数时间。但值得分析您的应用程序以验证这一点
话虽如此,您的应用程序的I/O可能没有您想象的那么慢。操作系统可能会读取并缓存包含元数据的磁盘块。读取文件元数据的系统调用大部分时间都将返回缓存信息。(当然,这是特定于操作系统的,取决于您使用的文件系统的类型。)AFAIK,这在Java中几乎是尽可能高效的。您可能可以压缩2%到5%,但这通常不是值得改进的性能 问题在于,典型的操作系统不提供一种方法来一次检索多个文件的元数据,或者一次检索多个元数据值 我希望元数据操作(
length()
,getLastModified()
等等)将占用绝大多数时间。但值得分析您的应用程序以验证这一点
话虽如此,您的应用程序的I/O可能没有您想象的那么慢。操作系统可能会读取并缓存包含元数据的磁盘块。读取文件元数据的系统调用大部分时间都将返回缓存信息。(当然,这是特定于操作系统的,取决于您使用的文件系统类型。)在您的情况下:
File[] listFiles = directory.listFiles();
将创建1000个文件
对象,但这些不是昂贵的I/O操作,因为新建文件()
在创建对象时不会执行IO操作,而文件输入流
会执行。但请注意,您仍然可以避免一次创建所有文件对象,并通过对漫游文件进行流式处理来减少消耗的内存。
返回
目录流
和返回流
的方法提供了实现此目的的方法。指出他们之间一些差异的帖子 因此,您可以通过以下方式使用
java.nio
API获得相同的结果:
Path directory = ...;
Files.newDirectoryStream(directory)
.forEach(p -> {
try {
String fileName = p.getFileName().toString();
String filePath = p.toAbsolutePath().toString();
long fileLen = Files.size(p);
long filelastModified = Files.getLastModifiedTime(p).toMillis();
} catch (IOException e) {
// FIXME to handle
}
});
编辑以供评论: 如果有子目录&需要检索 子目录中文件的详细信息 在这种情况下,
Files.walk()更合适,因为它是递归的。
它非常接近:
Path directory = ...;
Files.walk(directory)
.forEach(p -> {
try {
// same code ....
} catch (IOException e) {
// FIXME to handle
}
});
就你而言:
File[] listFiles = directory.listFiles();
将创建1000个文件
对象,但这些不是昂贵的I/O操作,因为新建文件()
在创建对象时不会执行IO操作,而文件输入流
会执行。
但请注意,您仍然可以避免一次创建所有文件对象,并通过对漫游文件进行流式处理来减少消耗的内存。
返回目录流
和返回流
的方法提供了实现此目的的方法。
指出他们之间一些差异的帖子
因此,您可以通过以下方式使用java.nio
API获得相同的结果:
Path directory = ...;
Files.newDirectoryStream(directory)
.forEach(p -> {
try {
String fileName = p.getFileName().toString();
String filePath = p.toAbsolutePath().toString();
long fileLen = Files.size(p);
long filelastModified = Files.getLastModifiedTime(p).toMillis();
} catch (IOException e) {
// FIXME to handle
}
});
编辑以供评论:
如果有子目录&需要检索
子目录中文件的详细信息
在这种情况下,Files.walk()更合适,因为它是递归的。
它非常接近:
Path directory = ...;
Files.walk(directory)
.forEach(p -> {
try {
// same code ....
} catch (IOException e) {
// FIXME to handle
}
});
我会使用File.list(),而不是listFiles(),它更接近本机api,前期创建的文件对象更少。但这只是一个小小的收获
更有趣的是,注意File.list()只返回子名称,因此您保存了几个getter,并且给定父级的所有子级的路径都相同,再次保存了更多琐碎的getter
您不会保存大小和日期,它们必须每个调用一次,抱歉。我会使用File.list(),而不是listFiles(),它更接近本机api,前期创建的文件对象更少。但这只是一个小小的收获
更有趣的是,注意File.list()只返回子名称,因此您保存了几个getter,并且给定父级的所有子级的路径都相同,再次保存了更多琐碎的getter
您不会在大小和日期上进行保存,很抱歉,它们必须一次调用一次。对于Java 7,Java.nio.file.DirectoryStream
提供了一种性能上获得巨大提升的替代方案
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
...
private static void nioDir( String filePath, int maxFiles )
throws IOException {
int i = 1;
Path dir = FileSystems.getDefault().getPath( filePath );
DirectoryStream<Path> stream = Files.newDirectoryStream( dir );
for (Path path : stream) {
System.out.println( "" + i + ": " + path.getFileName() );
if (++i > maxFiles) break;
}
stream.close();
}
import java.io.IOException;
导入java.nio.file.DirectoryStream;
导入java.nio.file.FileSystems;
导入java.nio.file.Files;
导入java.nio.file.Path;
...
私有静态void nioDir(字符串文件路径,int-maxFiles)
抛出IOException{
int i=1;
Path dir=FileSystems.getDefault().getPath(filePath);
DirectoryStream=Files.newDirectoryStream(dir);
用于(路径:流){
System.out.println(“+i+”:“+path.getFileName());
如果(++i>maxFiles)中断;
}
stream.close();
}
对于Java7,Java.nio.file.DirectoryStream
提供了