it-swarm.com.de

Größe des Ordners oder der Datei abrufen

Wie kann ich die Größe eines Ordners oder einer Datei in Java abrufen?

93
oneat
Java.io.File file = new Java.io.File("myfile.txt");
file.length();

Dies gibt die Länge der Datei in Bytes oder 0 zurück, wenn die Datei nicht vorhanden ist. Es gibt keine integrierte Methode, um die Größe eines Ordners zu ermitteln. Sie müssen die Verzeichnisstruktur rekursiv durchlaufen (mit der listFiles()-Methode eines Dateiobjekts, das ein Verzeichnis darstellt) und die Verzeichnisgröße für sich selbst sammeln:

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: Diese Methode ist für die Verwendung in der Produktion nicht ausreichend robust. directory.listFiles() kann null zurückgeben und eine NullPointerException verursachen. Es berücksichtigt auch keine Symlinks und hat möglicherweise andere Fehlermodi. Verwenden Sie diese Methode .

171
Tendayi Mawushe

Sie benötigen FileUtils#sizeOfDirectory(File) aus commons-io .

Beachten Sie, dass Sie manuell prüfen müssen, ob es sich bei der Datei um ein Verzeichnis handelt, da die Methode eine Ausnahme auslöst, wenn ein Nicht-Verzeichnis an sie übergeben wird.

WARNING: Diese Methode (ab Commons-io 2.4) hat einen Fehler und kann IllegalArgumentException auslösen, wenn das Verzeichnis gleichzeitig geändert wird.

35
yegor256

Mit Java-7 nio api kann die Berechnung der Ordnergröße wesentlich schneller durchgeführt werden.

Hier ist ein einsatzbereites Beispiel, das robust ist und keine Ausnahme auslöst. Es werden Verzeichnisse protokolliert, die nicht eingegeben werden können oder die Probleme beim Durchlaufen hatten. Symlinks werden ignoriert und die gleichzeitige Änderung des Verzeichnisses führt nicht zu mehr Problemen als nötig.

/**
 * 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
Aksel Willgert

In Java 8:

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

Es wäre schöner, Files::size im Kartenschritt zu verwenden, es wird jedoch eine markierte Ausnahme ausgelöst.

AKTUALISIEREN:
Sie sollten auch wissen, dass dies eine Ausnahme auslösen kann, wenn auf einige Dateien/Ordner nicht zugegriffen werden kann. Sehen Sie diese Frage und eine andere Lösung mit Guave .

10
Andrejs
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;
}
10
Vishal

Wenn Sie Java 8 NIO API verwenden möchten, gibt das folgende Programm die Größe des Verzeichnisses in Bytes aus, in dem es sich befindet.

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

}

Die calculateSize-Methode ist universell für Path-Objekte, daher funktioniert sie auch für die Dateien . Hinweis Wenn eine Datei oder ein Verzeichnis nicht zugänglich ist, lautet der zurückgegebene size des Pfadobjekts 0 .

4
dinomario10

So erhalten Sie am besten eine allgemeine Dateigröße (funktioniert für Verzeichnis und Nicht-Verzeichnis):

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

Bearbeiten: Beachten Sie, dass dies wahrscheinlich eine zeitraubende Operation sein wird. Führen Sie es nicht im UI-Thread aus.

Auch hier (entnommen aus https://stackoverflow.com/a/5599842/1696171 ) ist eine nette Methode, um aus den langen zurückgegebenen Zeilen einen benutzerlesbaren String zu erhalten:

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
Eric Cochran

File.length() ( Javadoc ).

Beachten Sie, dass dies für Verzeichnisse nicht funktioniert oder nicht garantiert funktioniert.

Was möchten Sie für ein Verzeichnis? Wenn es sich um die Gesamtgröße aller darunter liegenden Dateien handelt, können Sie unter Verwendung von File.list() und File.isDirectory() rekursiv durch Kinder gehen und deren Größe summieren.

3
danben

Das File-Objekt hat eine length-Methode:

f = new File("your/file/name");
f.length();
3
JesperE

Für Java 8 ist dies eine richtige Möglichkeit, dies zu tun:

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

Es ist wichtig, alle Verzeichnisse herauszufiltern , da die Längenmethode für Verzeichnisse nicht 0 ist.

Zumindest dieser Code liefert die gleiche Größeninformation wie der Windows Explorer.

3
wumpz
  • Funktioniert für Android und Java
  • Funktioniert für Ordner und Dateien
  • Sucht überall dort, wo er benötigt wird, auf Nullzeiger
  • Ignoriert symbolischer Link Abkürzungen 
  • Produktion fertig!

Quellcode:

   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());
    }
2
Ilya Gazman

in Linux, wenn Sie Verzeichnisse sortieren wollen, dann du -hs * | sort -h

0
Prem S
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;
    }
0
Nicholas

für Windows ist die Verwendung von Java.io diese rekursive Funktion nützlich.

    public static long folderSize(File directory) {
    long length = 0;

    if (directory.isFile())
         length += directory.length();
    else{
        for (File file : directory.listFiles()) {
             if (file.isFile())
                 length += file.length();
             else
                 length += folderSize(file);
        }
    }

    return length;
}

Das ist getestet und funktioniert auf meiner Seite einwandfrei.

0
It's PD

Nach vielem Nachforschen und Nachdenken über verschiedene hier bei StackOverflow vorgeschlagene Lösungen. Ich entschied mich schließlich, meine eigene Lösung zu schreiben. Mein Zweck ist ein No-Throw-Mechanismus, da ich nicht abstürzen möchte, wenn die API die Ordnergröße nicht abrufen kann. Diese Methode eignet sich nicht für Multithread-Szenarien.

Zunächst möchte ich beim Durchlaufen des Dateisystembaums nach gültigen Verzeichnissen suchen.

private static boolean isValidDir(File dir){
    if (dir != null && dir.exists() && dir.isDirectory()){
        return true;
    }else{
        return false;
    }
}

Zweitens möchte ich nicht, dass mein rekursiver Aufruf in Symlinks (Softlinks) geht und die Größe in das Gesamtaggregat einbezieht.

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

Schließlich meine rekursionsbasierte Implementierung, um die Größe des angegebenen Verzeichnisses abzurufen. Beachten Sie die Nullprüfung für dir.listFiles (). Laut Javadoc besteht die Möglichkeit, dass diese Methode null zurückgeben kann.

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

Etwas Sahne auf dem Kuchen, die API, um die Größe der Liste Dateien (möglicherweise alle Dateien und Ordner unter root) zu erhalten.

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;
}
0
A.B.