如何在Java中获取文件夹或文件的大小?
java.io.File file = new java.io.File("myfile.txt");
file.length();
如果文件存在,则返回文件的字节数长度,否则返回0
。没有内置的方法可以获取文件夹的大小,您需要递归遍历目录树(使用表示目录的文件对象的listFiles()
方法)并自己累加目录大小:
public static long folderSize(File directory) {
long length = 0;
for (File file : directory.listFiles()) {
if (file.isFile())
length += file.length();
else
length += folderSize(file);
}
return length;
}
警告: 此方法不足以用于生产环境。 directory.listFiles()
可能会返回 null
并引发 NullPointerException
异常。此外,它不考虑符号链接和其他可能的故障模式。请使用此方法。
/**
* Attempts to calculate the size of a file or directory.
*
* <p>
* Since the operation is non-atomic, the returned value may be inaccurate.
* However, this method is quick and does its best.
*/
public static long size(Path path) {
final AtomicLong size = new AtomicLong(0);
try {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
size.addAndGet(attrs.size());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
System.out.println("skipped: " + file + " (" + exc + ")");
// Skip folders that can't be traversed
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
if (exc != null)
System.out.println("had trouble traversing: " + dir + " (" + exc + ")");
// Ignore errors traversing a folder
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
throw new AssertionError("walkFileTree will not throw IOException if the FileVisitor does not");
}
return size.get();
}
AtomicLong
而不是仅使用long
有什么原因吗? - Lukas SchmelzeisenFiles
不直接支持它! - Aleksandr Dubinsky您需要使用FileUtils#sizeOfDirectory(File)
,它来自于commons-io。
请注意,您需要手动检查文件是否为目录,因为如果传递非目录,则该方法会抛出异常。
警告:此方法(截至commons-io 2.4)存在错误,如果目录同时被修改,可能会抛出IllegalArgumentException
异常。
checkDirectory(directory);
检查后的代码行。请确保 File.listFiles
有子项。 参考文献: FileUtils.sizeOfDirectory(), File.listFiles() - Mr. Polywhirlpublic static long getFolderSize(File dir) {
long size = 0;
for (File file : dir.listFiles()) {
if (file.isFile()) {
System.out.println(file.getName() + " " + file.length());
size += file.length();
}
else
size += getFolderSize(file);
}
return size;
}
size += getFolderSize(file);
- Teja Kantamneni对于Java 8,这是正确的做法:
Files.walk(new File("D:/temp").toPath())
.map(f -> f.toFile())
.filter(f -> f.isFile())
.mapToLong(f -> f.length()).sum()
过滤掉所有的目录非常重要,因为长度方法并不能保证对于目录来说长度一定是0。
至少这段代码提供了与Windows资源管理器相同的文件大小信息。
以下是获取一般文件大小的最佳方法(适用于目录和非目录):
public static long getSize(File file) {
long size;
if (file.isDirectory()) {
size = 0;
for (File child : file.listFiles()) {
size += getSize(child);
}
} else {
size = file.length();
}
return size;
}
编辑:请注意这可能是一个耗时的操作,不要在UI线程上运行。
此外,在这里(摘自https://dev59.com/33A75IYBdhLWcg3wfpKr#5599842)有一种很好的方法来从返回的长整型中获取用户可读的字符串:
public static String getReadableSize(long size) {
if(size <= 0) return "0";
final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(size)/Math.log10(1024));
return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups))
+ " " + units[digitGroups];
}
File.length()
(Javadoc).
请注意,此方法不能用于目录,或者不能保证能正常工作。
对于目录,您想要什么?如果是其下所有文件的总大小,您可以使用File.list()
和File.isDirectory()
递归遍历子目录并累加它们的大小。
File
对象有一个length
方法:
f = new File("your/file/name");
f.length();
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathSize {
public static void main(String[] args) {
Path path = Paths.get(".");
long size = calculateSize(path);
System.out.println(size);
}
/**
* Returns the size, in bytes, of the specified <tt>path</tt>. If the given
* path is a regular file, trivially its size is returned. Else the path is
* a directory and its contents are recursively explored, returning the
* total sum of all files within the directory.
* <p>
* If an I/O exception occurs, it is suppressed within this method and
* <tt>0</tt> is returned as the size of the specified <tt>path</tt>.
*
* @param path path whose size is to be returned
* @return size of the specified path
*/
public static long calculateSize(Path path) {
try {
if (Files.isRegularFile(path)) {
return Files.size(path);
}
return Files.list(path).mapToLong(PathSize::calculateSize).sum();
} catch (IOException e) {
return 0L;
}
}
}
calculateSize
方法对于Path
对象是通用的,因此也适用于文件。
注意,如果文件或目录无法访问,则路径对象返回的大小将为0
。
StatFs
。它使用文件系统统计信息,比递归方法快近1000倍,而我们的需求无法使用递归方法。我们的实现可以在这里找到:https://dev59.com/M6rka4cB1Zd3GeqPc2Sn#58418639 - Joshua Pinter