Получить размер папки или файла - PullRequest
96 голосов
/ 27 января 2010

Как я могу получить размер папки или файла в Java?

Ответы [ 14 ]

175 голосов
/ 27 января 2010
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.Кроме того, он не учитывает символические ссылки и, возможно, имеет другие режимы сбоя.Используйте этот метод .

38 голосов
/ 09 ноября 2013

Используя java-7 nio api, вычислить размер папки можно гораздо быстрее.

Вот готовый пример, который является надежным и не выдает исключение. Он будет регистрировать каталоги, в которые он не может войти или имел проблемы с прохождением. Символьные ссылки игнорируются, и одновременное изменение каталога не вызовет больше проблем, чем необходимо.

/**
 * 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();
}
34 голосов
/ 02 июля 2012

Вам нужно FileUtils#sizeOfDirectory(File) из commons-io .

Обратите внимание, что вам нужно будет вручную проверить, является ли файл каталогом, так как метод выдает исключение, если ему передается не каталог.

ПРЕДУПРЕЖДЕНИЕ : этот метод (по состоянию на commons-io 2.4) содержит ошибку и может выдать IllegalArgumentException, если каталог одновременно изменен.

16 голосов
/ 14 июля 2014

В Java 8:

long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum();

Было бы лучше использовать Files::size на шаге карты, но выдает проверенное исключение.

UPDATE:
Вы также должны знать, что это может вызвать исключение, если некоторые файлы / папки недоступны. Посмотрите этот вопрос и другое решение, используя Гуава .

10 голосов
/ 27 января 2010
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;
}
4 голосов
/ 04 марта 2017

Если вы хотите использовать Java 8 NIO API, следующая программа напечатает размер каталога в байтах, в котором она находится.

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.

4 голосов
/ 21 февраля 2017

Для Java 8 это один правильный способ сделать это:

Files.walk(new File("D:/temp").toPath())
                .map(f -> f.toFile())
                .filter(f -> f.isFile())
                .mapToLong(f -> f.length()).sum()

Важно отфильтровать все каталоги , потому что метод длины не гарантируется равным 0 для каталогов.

По крайней мере этот код предоставляет ту же информацию о размере, что и сам Windows Explorer.

3 голосов
/ 15 октября 2017
  • Работает для Android и Java
  • Работает как для папок, так и для файлов
  • Проверяет нулевой указатель везде, где это необходимо
  • Игнорирует символическая ссылка aka ярлыки
  • Производство готово!

Исходный код:

   public long fileSize(File root) {
        if(root == null){
            return 0;
        }
        if(root.isFile()){
            return root.length();
        }
        try {
            if(isSymlink(root)){
                return 0;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }

        long length = 0;
        File[] files = root.listFiles();
        if(files == null){
            return 0;
        }
        for (File file : files) {
            length += fileSize(file);
        }

        return length;
    }

    private static boolean isSymlink(File file) throws IOException {
        File canon;
        if (file.getParent() == null) {
            canon = file;
        } else {
            File canonDir = file.getParentFile().getCanonicalFile();
            canon = new File(canonDir, file.getName());
        }
        return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
    }
3 голосов
/ 22 августа 2014

Вот лучший способ получить общий размер файла (работает для каталога и не-каталога):

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;
}

Изменить: Обратите внимание, что это, вероятно, будет трудоемкой операцией. Не запускайте его в потоке пользовательского интерфейса.

Кроме того, здесь (взято из 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];
}
3 голосов
/ 27 января 2010

Объект File имеет метод length:

f = new File("your/file/name");
f.length();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...