14 ответов:
java.io.File file = new java.io.File("myfile.txt"); file.length();это возвращает длину файла в байтах или
0Если файл не существует. Нет встроенного способа получить размер папки, вам придется ходить по дереву каталогов рекурсивно (используяlistFiles()метод объекта file, который представляет каталог) и накапливать размер каталога для себя: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. Кроме того, он не учитывает символические ссылки и, возможно, имеет другие режимы сбоя. Используйте этот метод.
вам нужно
FileUtils#sizeOfDirectory(File)С commons-io.обратите внимание, что вам нужно будет вручную проверить, является ли файл каталогом, поскольку метод вызывает исключение, если в него передается не каталог.
предупреждение: этот метод (по состоянию на commons-io 2.4) имеет ошибку и может бросить
IllegalArgumentExceptionесли каталог одновременно изменяется.
используя 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(); }
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; }
В Java 8:
long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum();было бы лучше использовать
Files::sizeна шаге карты, но он выдает проверенное исключение.обновление:
Вы также должны знать, что это может вызвать исключение, если некоторые файлы/папки не доступны. Смотрите это вопрос и другое решение с помощью гуавы.
если вы хотите использовать 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; } } }The
calculateSizeметод универсален дляPathобъекты, поэтому он также работает для файлов. Примечание что если файл или каталог недоступен, в этом случае возвращается в размере путь объекта будет0.
File.length()(документация).обратите внимание, что это не работает для каталогов, или это не обязательно сработает.
для каталога, что вы хотите? Если это общий размер всех файлов под ним, вы можете рекурсивно ходить детей с помощью
File.list()иFile.isDirectory()и сумма их размеров.
вот лучший способ получить общий размер файла (работает для каталога и не-каталога):
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: обратите внимание, что это, вероятно, будет длительная операция. Не запускайте его в потоке пользовательского интерфейса.
кроме того, здесь (взято из https://stackoverflow.com/a/5599842/1696171) - это хороший способ получить читаемую пользователем строку из long returned:
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]; }
на Java 8 Это один правильный способ сделать это:
Files.walk(new File("D:/temp").toPath()) .map(f -> f.toFile()) .filter(f -> f.isFile()) .mapToLong(f -> f.length()).sum()важно отфильтровать все каталоги, потому что метод длины не гарантируется равным 0 для каталогов.
по крайней мере, этот код предоставляет такую же информацию о размере, как и сам проводник Windows.
- работает Android и Java
- работает как для папок, так и для файлов
- проверяет наличие нулевого указателя везде, где это необходимо
- игнорировать символическую ссылку ярлыков ака
- производства готов!
исходный код:
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()); }
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; }
После много исследований и изучения различных решений, предлагаемых здесь на StackOverflow. Я, наконец, решил написать свое решение. Моя цель-иметь механизм без броска, потому что я не хочу аварийно завершать работу, если API не может получить размер папки. этот метод не подходит для многопоточного сценария.
прежде всего, я хочу проверить наличие допустимых каталогов при переходе вниз по дереву файловой системы.
private static boolean isValidDir(File dir){ if (dir != null && dir.exists() && dir.isDirectory()){ return true; }else{ return false; } }второй я не хочу мой рекурсивный вызов, чтобы перейти в символические ссылки (softlinks) и включить размер в общей совокупности.
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()); }наконец, моя реализация на основе рекурсии, чтобы получить размер указанного каталога. Обратите внимание на нулевую проверку для dir.файл-список(). Согласно 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; } }некоторые сливки на торте, 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; }
Comments