web-dev-qa-db-ja.com

フォルダーまたはファイルのサイズを取得する

Javaでフォルダーまたはファイルのサイズを取得するにはどうすればよいですか?

98
oneat
_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;
}
_

[〜#〜] warning [〜#〜]:この方法は、本番環境での使用には十分に堅牢ではありません。 directory.listFiles()nullを返し、NullPointerExceptionを引き起こす場合があります。また、シンボリックリンクを考慮せず、おそらく他の障害モードがあります。 このメソッド を使用します。

181
Tendayi Mawushe

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

FileUtils#sizeOfDirectory(File) from commons-io が必要です。

非ディレクトリが渡された場合、メソッドは例外をスローするため、ファイルがディレクトリであるかどうかを手動で確認する必要があることに注意してください。

[〜#〜] warning [〜#〜]:この方法(commons-io 2.4以降)にはバグがあり、IllegalArgumentExceptionディレクトリが同時に変更された場合。

35
yegor256

In Java 8:

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

マップステップでFiles::sizeを使用する方が適切ですが、チェック済み例外がスローされます。

更新:
ファイル/フォルダーの一部にアクセスできない場合、例外がスローされる可能性があることにも注意してください。これを参照してください question および Guava を使用した別のソリューション。

18
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

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オブジェクトに対して汎用的であるため、ファイルに対しても機能します。 ファイルまたはディレクトリにアクセスできない場合、この場合、パスオブジェクトの返されたsize0

4
dinomario10

Java 8の場合、これは正しい方法の1つです。

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

すべてのディレクトリを除外することが重要です。これは、ディレクトリの長さのメソッドが0であることが保証されていないためです。

少なくともこのコードは、Windowsエクスプローラー自体と同じサイズ情報を提供します。

4
wumpz

一般的なファイルのサイズを取得する最良の方法は次のとおりです(ディレクトリおよび非ディレクトリで機能します)。

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

編集:これはおそらく時間のかかる操作になることに注意してください。 UIスレッドで実行しないでください。

また、ここ( 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
Eric Cochran

File.length()Javadoc )。

これはディレクトリでは機能しないか、動作が保証されていないことに注意してください。

ディレクトリの場合、何が必要ですか?その下のすべてのファイルの合計サイズであれば、File.list()File.isDirectory()を使用して子を再帰的にウォークし、サイズを合計できます。

3
danben

Fileオブジェクトにはlengthメソッドがあります:

f = new File("your/file/name");
f.length();
3
JesperE
  • AndroidおよびJavaに対応
  • フォルダーとファイルの両方に対応
  • 必要なすべての場所でNULLポインターをチェックします
  • 無視 シンボリックリンク 別名ショートカット
  • 生産準備完了!

ソースコード:

   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
Ilya Gazman

linuxでは、ディレクトリをソートする場合はdu -hs * |ソート-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

windowsの場合、Java.ioを使用すると、この再帰関数が便利です。

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

これはテストされており、私の側で適切に機能しています。

0
It's PD

ここでStackOverflowで提案されたさまざまなソリューションについて多くの調査と調査を行いました。私は最終的に独自のソリューションを作成することにしました。 APIがフォルダーサイズを取得できない場合にクラッシュしたくないので、私の目的はノースローメカニズムを持つことです。 この方法はマルチスレッドのシナリオには適していません。

まず、ファイルシステムツリーをたどっていく間に、有効なディレクトリを確認したいと思います。

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

第二に、再帰呼び出しがシンボリックリンク(ソフトリンク)に入り、合計サイズにサイズを含めないようにします。

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.listFiles()のnullチェックに注意してください。 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;
}
0
A.B.