Java 获取文件夹或文件的大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2149785/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get size of folder or file
提问by oneat
How can I retrieve size of folder or file in Java?
如何在 Java 中检索文件夹或文件的大小?
采纳答案by Tendayi Mawushe
java.io.File file = new java.io.File("myfile.txt");
file.length();
This returns the length of the file in bytes or 0
if the file does not exist. There is no built-in way to get the size of a folder, you are going to have to walk the directory tree recursively (using the listFiles()
method of a file object that represents a directory) and accumulate the directory size for yourself:
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;
}
WARNING: This method is not sufficiently robust for production use. directory.listFiles()
may return null
and cause a NullPointerException
. Also, it doesn't consider symlinks and possibly has other failure modes. Use this method.
警告:此方法不足以用于生产用途。directory.listFiles()
可能会返回null
并导致NullPointerException
. 此外,它不考虑符号链接,可能还有其他故障模式。使用此方法。
回答by danben
File.length()
(Javadoc).
File.length()
( Javadoc)。
Note that this doesn't work for directories, or is not guaranteed to work.
请注意,这不适用于目录,或者不能保证工作。
For a directory, what do you want? If it's the total size of all files underneath it, you can recursively walk children using File.list()
and File.isDirectory()
and sum their sizes.
对于目录,您想要什么?如果它是它下面所有文件的总大小,您可以使用File.list()
和递归地遍历孩子File.isDirectory()
并总结他们的大小。
回答by JesperE
The File
object has a length
method:
该File
对象有一个length
方法:
f = new File("your/file/name");
f.length();
回答by Vishal
public 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;
}
回答by yegor256
You need FileUtils#sizeOfDirectory(File)
from commons-io.
你需要FileUtils#sizeOfDirectory(File)
来自commons-io。
Note that you will need to manually check whether the file is a directory as the method throws an exception if a non-directory is passed to it.
请注意,您将需要手动检查文件是否为目录,因为如果将非目录传递给该方法会引发异常。
WARNING: This method (as of commons-io 2.4) has a bug and may throw IllegalArgumentException
if the directory is concurrently modified.
警告:此方法(从 commons-io 2.4 开始)有一个错误,IllegalArgumentException
如果同时修改目录,则可能会抛出错误。
回答by Aksel Willgert
Using java-7 nio api, calculating the folder size can be done a lot quicker.
使用java-7 nio api,可以更快地计算文件夹大小。
Here is a ready to run example that is robust and won't throw an exception. It will log directories it can't enter or had trouble traversing. Symlinks are ignored, and concurrent modification of the directory won't cause more trouble than necessary.
这是一个准备运行的例子,它很健壮,不会抛出异常。它将记录无法进入或无法遍历的目录。符号链接被忽略,并且目录的并发修改不会造成不必要的麻烦。
/**
* 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();
}
回答by Andrejs
In Java 8:
在 Java 8 中:
long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum();
It would be nicer to use Files::size
in the map step but it throws a checked exception.
Files::size
在地图步骤中使用会更好,但它会抛出一个已检查的异常。
UPDATE:
You should also be aware that this can throw an exception if some of the files/folders are not accessible. See this questionand another solution using Guava.
回答by Eric Cochran
Here's the best way to get a general File's size (works for directory and non-directory):
这是获取一般文件大小的最佳方法(适用于目录和非目录):
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;
}
Edit: Note that this is probably going to be a time-consuming operation. Don't run it on the UI thread.
编辑:请注意,这可能是一项耗时的操作。不要在 UI 线程上运行它。
Also, here (taken from https://stackoverflow.com/a/5599842/1696171) is a nice way to get a user-readable String from the long returned:
此外,这里(取自https://stackoverflow.com/a/5599842/1696171)是从长返回中获取用户可读字符串的好方法:
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];
}
回答by Nicholas
public long folderSize (String directory)
{
File curDir = new File(directory);
long length = 0;
for(File f : curDir.listFiles())
{
if(f.isDirectory())
{
for ( File child : f.listFiles())
{
length = length + child.length();
}
System.out.println("Directory: " + f.getName() + " " + length + "kb");
}
else
{
length = f.length();
System.out.println("File: " + f.getName() + " " + length + "kb");
}
length = 0;
}
return length;
}
回答by A.B.
After lot of researching and looking into different solutions proposed here at StackOverflow. I finally decided to write my own solution. My purpose is to have no-throw mechanism because I don't want to crash if the API is unable to fetch the folder size. This method is not suitable for mult-threaded scenario.
经过大量研究和研究在 StackOverflow 上提出的不同解决方案。我最终决定编写自己的解决方案。我的目的是拥有不抛出机制,因为如果 API 无法获取文件夹大小,我不想崩溃。此方法不适用于多线程场景。
First of all I want to check for valid directories while traversing down the file system tree.
首先,我想在遍历文件系统树时检查有效目录。
private static boolean isValidDir(File dir){
if (dir != null && dir.exists() && dir.isDirectory()){
return true;
}else{
return false;
}
}
Second I do not want my recursive call to go into symlinks (softlinks) and include the size in total aggregate.
其次,我不希望我的递归调用进入符号链接(软链接)并将大小包含在总聚合中。
public static boolean isSymlink(File file) throws IOException {
File canon;
if (file.getParent() == null) {
canon = file;
} else {
canon = new File(file.getParentFile().getCanonicalFile(),
file.getName());
}
return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
}
Finally my recursion based implementation to fetch the size of the specified directory. Notice the null check for dir.listFiles(). According to javadoc there is a possibility that this method can return null.
最后,我基于递归的实现来获取指定目录的大小。请注意 dir.listFiles() 的空检查。根据 javadoc,此方法有可能返回 null。
public static long getDirSize(File dir){
if (!isValidDir(dir))
return 0L;
File[] files = dir.listFiles();
//Guard for null pointer exception on files
if (files == null){
return 0L;
}else{
long size = 0L;
for(File file : files){
if (file.isFile()){
size += file.length();
}else{
try{
if (!isSymlink(file)) size += getDirSize(file);
}catch (IOException ioe){
//digest exception
}
}
}
return size;
}
}
Some cream on the cake, the API to get the size of the list Files (might be all of files and folder under root).
一些锦上添花,API 获取列表文件的大小(可能是根目录下的所有文件和文件夹)。
public static long getDirSize(List<File> files){
long size = 0L;
for(File file : files){
if (file.isDirectory()){
size += getDirSize(file);
} else {
size += file.length();
}
}
return size;
}