2010-01-27 20 views

Antwort

158
java.io.File file = new java.io.File("myfile.txt"); 
file.length(); 

Dies gibt die Länge der Datei, in Bytes oder 0 Wenn die Datei nicht existiert. Es gibt keine integrierte Methode, um die Größe eines Ordners zu erhalten. Sie müssen den Verzeichnisbaum rekursiv durchlaufen (mit der Methode listFiles() eines Dateiobjekts, das ein Verzeichnis darstellt) und die Verzeichnisgröße für sich selbst akkumulieren:

WARNUNG: Diese Methode ist nicht ausreichend robust für den Produktionseinsatz. directory.listFiles() kann null zurückgeben und eine NullPointerException verursachen. Außerdem berücksichtigt es keine Symlinks und möglicherweise andere Fehlermodi. Verwenden Sie this method.

+19

+1 wie diese bereit um Beispiele auszuführen – stacker

+11

Seien Sie vorsichtig, wenn Sie dies auf einem Windows-Computer im Verzeichnis C: root ausführen; Da ist eine Systemdatei, die (laut java.io.File) weder eine Datei noch ein Verzeichnis enthält. Möglicherweise möchten Sie die else-Klausel ändern, um zu überprüfen, ob die Datei tatsächlich ein Verzeichnis ist. –

+2

Einfache Änderung, um den Parameter zu überprüfen, ob es kein Verzeichnis am Anfang der Methode ist und die Länge zurückgibt, dann ist die Rekursion einfacher - fügen Sie einfach den Aufruf zu self in der gleichen Methode hinzu, und das unterstützt das Übergeben einer Dateireferenz anstatt eines Verzeichnisses auch. –

3

File.length() (Javadoc).

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

Für ein Verzeichnis, was willst du? Wenn es die Gesamtgröße aller darunter liegenden Dateien ist, können Sie rekursiv unter Verwendung von File.list() und File.isDirectory() Kinder spazieren gehen und ihre Größe summieren.

3

Das File Objekt eine length Methode:

f = new File("your/file/name"); 
f.length(); 
10
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; 
} 
+1

@Vishal Ihr Code muss eine einfache Lösung haben, im rekursiven Aufruf sollten Sie die Größe der vorhandenen Größe hinzufügen, nicht nur zuweisen. 'size + = getFolderSize (Datei);' –

+0

@Teja: Danke für das Hinweis, aber die Änderungen werden in der if-Anweisung auch – Vishal

+0

Manchmal in einem * wachsenden * Ordner (ein anderer Thread lädt Dateien und Ordner und an der Gleichzeitig drucke ich Ordnergröße als fortschreitend) es gibt ** nullpointerexception ** at line "für (Datei: dir.listFiles()) {". Einige Dateien erscheinen und verschwinden schnell in einem lebenden Ordner. Also habe ich einen Null-Check für * dir.listFiles() * Rückgabewert vor for-Schleife hinzugefügt. – csonuryilmaz

29

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

Beachten Sie, dass Sie manuell überprü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.

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

+0

Was passiert also, wenn die Datei kein Verzeichnis ist? wenn es nicht existiert? etc - wie schrecklich docs –

+0

@Mr_and_Mrs_D - Kopieren Sie einfach die Zeilen nach dem 'checkDirectory (directory);' check. Stellen Sie nur sicher, dass 'File.listFiles' Kinder enthält. ** Refs: ** [FileUtils.sizeOfDirectory()] (http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/2.4/org/apache/commons/io/ FileUtils.java # FileUtils.sizeOfDirectory% 28java.io.File% 29), [Datei.listFiles()] (http://docs.oracle.com/javase/6/docs/api/java/io/File.html #listFiles) –

+2

Siehe Fehler [IO-449] (https://issues.apache.org/jira/browse/IO-449). Diese Methode wird eine 'IllegalArgumentException' auslösen, wenn das Verzeichnis während der Iteration geändert wird. –

27

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

Hier ist ein bereit zum Ausführen Beispiel, das robust ist und keine Ausnahme auslösen wird. Es protokolliert Verzeichnisse, die nicht eingegeben werden können oder Probleme beim Traversieren hatten. Symlinks werden ignoriert, und die gleichzeitige Änderung des Verzeichnisses verursacht keine größeren Probleme 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(); 
} 
+0

Gibt es eine Entsprechung für diese Android-Entwicklung? –

+0

Gibt es einen Grund, 'AtomicLong' anstelle von' long' zu verwenden? –

+0

Die Variable muss endgültig sein, wenn auf die anonyme Klasse –

8

In Java 8:

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

Es wäre schöner, Files::size in der Karte Schritt zu verwenden, aber es wirft eine geprüfte Ausnahme.

UPDATE:
Sie sollten auch beachten, dass dies eine Ausnahme auslösen kann, wenn einige der Dateien/Ordner nicht zugänglich sind. Siehe hierzu question und eine andere Lösung unter Verwendung von Guava.

+1

Ich sah in etwas ähnlich und endete mit dem Code in Frage: http://StackOverflow.com/Questions/22867286/ Dateien-Gehen-Berechnen-Gesamt-Größe, wie Sie sehen, gibt es einen anderen Aspekt der Fehlerbehandlung, der ebenfalls Probleme verursacht. –

+0

@AkselWillgert Danke, das ist bedauerlich und ich habe die Antwort aktualisiert. Wechseln Sie nun zu Guava http://StackOverflow.com/a/24757556/1180621 – Andrejs

2

Hier ist der beste Weg, um eine allgemeine Datei Größe zu erhalten (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; 
} 

Edit: Beachten Sie, dass dies wahrscheinlich ein zeitaufwendiger Vorgang sein wird. Führen Sie es nicht im UI-Thread aus.

Auch hier (aus https://stackoverflow.com/a/5599842/1696171) ist ein guter Weg, einen Benutzer lesbaren String aus dem langen zurückgekehrt zu bekommen:

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

Nach vieler Forschung und der Suche in verschiedene Lösungen, die hier vorgeschlagen bei Paketüberfluss. Ich entschied mich schließlich, meine eigene Lösung zu schreiben. Mein Ziel ist ein No-Throw-Mechanismus, weil ich nicht abstürzen will, wenn die API die Ordnergröße nicht abrufen kann. Diese Methode ist nicht für Multithread-Szenarien geeignet.

Zuerst möchte ich nach gültigen Verzeichnissen suchen, während ich den Dateisystembaum durchlaufe.

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

Zweitens möchte ich nicht meine rekursive Aufruf in Symlinks (Softlinks) gehen und die Größe in Gesamtaggregat enthalten.

Endlich meine rekursiv basierte Implementierung, um die Größe des angegebenen Verzeichnisses abzurufen. Beachten Sie die Nullprüfung für dir.listFiles(). Laut Javadoc gibt es eine Möglichkeit, dass diese Methode null zurückgeben kann.

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

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

Für Java 8 dies ist eine richtige Weg, es 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, um herauszufiltern, da die Länge Methode nicht als 0 ist garantiert für Verzeichnisse.

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

2

Wenn Sie Java 8 NIO API verwenden möchten, wird das folgende Programm die Größe drucken, in Bytes, des Verzeichnisses 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 , so funktioniert es auch für Dateien. Hinweis Wenn die Datei oder das Verzeichnis nicht zugänglich ist, wird in diesem Fall die zurückgegebene Größe des Pfadobjekts 0.

0

in Linux, wenn Sie Verzeichnisse dann du -hs * | sortieren möchten -h Art

1
  • Works für Android und Java
  • Works für beide Ordner und Dateien
  • Checks für Null-Zeiger überall gebraucht, wo
  • Ignoriert symbolic link aka Abkürzungen
  • Produktion bereit !

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