web-dev-qa-db-ja.com

AndroidでSDカードのフォルダーのサイズを取得するにはどうすればよいですか?

SDカード上のフォルダのサイズを簡単に取得することはできますか?画像のキャッシュにフォルダーを使用し、キャッシュされたすべての画像の合計サイズを表示したいと思います。各ファイルを繰り返す以外にこれを行う方法はありますか?それらはすべて同じフォルダ内にありますか?

28
Gunnar Lium

すべてのファイルを調べて、それらの長さを合計します。

/**
 * Return the size of a directory in bytes
 */
private static long dirSize(File dir) {

    if (dir.exists()) {
        long result = 0;
        File[] fileList = dir.listFiles();
        for(int i = 0; i < fileList.length; i++) {
            // Recursive call if it's a directory
            if(fileList[i].isDirectory()) {
                result += dirSize(fileList [i]);
            } else {
                // Sum the file size in bytes
                result += fileList[i].length();
            }
        }
        return result; // return the file size
    }
    return 0;
}

注:関数は手動で記述されているため、コンパイルできませんでした!

編集:再帰呼び出しが修正されました。

編集:dirList.lengthがfileList.lengthに変更されました。

39
Moss

再帰を回避し、論理サイズではなく物理サイズを計算するコードを次に示します。

public static long getFileSize(final File file) {
    if (file == null || !file.exists())
        return 0;
    if (!file.isDirectory())
        return file.length();
    final List<File> dirs = new LinkedList<>();
    dirs.add(file);
    long result = 0;
    while (!dirs.isEmpty()) {
        final File dir = dirs.remove(0);
        if (!dir.exists())
            continue;
        final File[] listFiles = dir.listFiles();
        if (listFiles == null || listFiles.length == 0)
            continue;
        for (final File child : listFiles) {
            result += child.length();
            if (child.isDirectory())
                dirs.add(child);
        }
    }
    return result;
}
15

このコードを使用する必要があります:

public static long getFolderSize(File f) {
    long size = 0;
    if (f.isDirectory()) {
        for (File file : f.listFiles()) {    
            size += getFolderSize(file);
        }
    } else {
        size=f.length();
    }
    return size;
}
5
Linh Toòng
/**
 * Try this one for better performance
 * Mehran
 * Return the size of a directory in bytes
 **/

private static long dirSize(File dir) {
    long result = 0;

    Stack<File> dirlist= new Stack<File>();
    dirlist.clear();

    dirlist.Push(dir);

    while(!dirlist.isEmpty())
    {
        File dirCurrent = dirlist.pop();

        File[] fileList = dirCurrent.listFiles();
        for(File f: fileList){
            if(f.isDirectory())
                dirlist.Push(f);
            else
                result += f.length();
        }
    }

    return result;
}
5
Mehran

#Mossのやり方は正しいです。これは、バイトを人間が読める形式に変更したい人のための私のコードです。フォルダーのパスをdirSize(String path)に割り当て、バイト、キロ、メガなどに基づいて人間が読める形式にする必要があります。

private static String dirSize(String path) {

        File dir = new File(path);

        if(dir.exists()) {
            long bytes = getFolderSize(dir);
            if (bytes < 1024) return bytes + " B";
            int exp = (int) (Math.log(bytes) / Math.log(1024));
            String pre = ("KMGTPE").charAt(exp-1) + "";

            return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
        }

        return "0";
    }

    public static long getFolderSize(File dir) {
        if (dir.exists()) {
            long result = 0;
            File[] fileList = dir.listFiles();
            for(int i = 0; i < fileList.length; i++) {
                // Recursive call if it's a directory
                if(fileList[i].isDirectory()) {
                    result += getFolderSize(fileList[i]);
                } else {
                    // Sum the file size in bytes
                    result += fileList[i].length();
                }
            }
            return result; // return the file size
        }
        return 0;
    } 
3
Hesam

他のソリューションの問題は、指定されたディレクトリ内のすべてのファイルの論理サイズのみを提供することです。実際の(物理的な)使用スペースとは異なります。ディレクトリに多数のサブディレクトリや小さなファイルがある場合、ディレクトリの論理サイズと実際のサイズに大きな違いがある可能性があります。

これが、FSの物理構造をカウントする方法を見つけたものです。

public static long getDirectorySize(File directory, long blockSize) {
    File[] files = directory.listFiles();
    if (files != null) {

        // space used by directory itself 
        long size = file.length();

        for (File file : files) {
            if (file.isDirectory()) {
                // space used by subdirectory
                size += getDirectorySize(file, blockSize);
            } else {
                // file size need to rounded up to full block sizes
                // (not a perfect function, it adds additional block to 0 sized files
                // and file who perfectly fill their blocks) 
                size += (file.length() / blockSize + 1) * blockSize;
            }
        }
        return size;
    } else {
        return 0;
    }
}

StatFs を使用してブロックサイズを取得できます。

public static long getDirectorySize(File directory) {
    StatFs statFs = new StatFs(directory.getAbsolutePath());
    long blockSize;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        blockSize = statFs.getBlockSizeLong()
    } else {
        blockSize = statFs.getBlockSize();
    }

    return getDirectorySize(directory, blockSize);
}
3

お役に立てれば

これをインポート

import Android.text.format.Formatter;

ファイルサイズについて

public static String fileSize(File file, Context context) {
        return Formatter.formatFileSize(context, file.length());
    }

フォルダーサイズについて

 public static String forlderSize(File file, Context context) {
        long length = 0;
        File[] folderFiles = file.listFiles();
        for (File f : folderFiles) {
            length += f.length();
        }

        return Formatter.formatFileSize(context, length);
    }
1
zaai

以下のメソッドはフォルダのサイズを返します:-

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

上記のメソッドを呼び出す:-

File file = new File(Environment.getExternalStorageDirectory().getPath()+"/urfoldername/");

long folder_size=getFolderSize(file);

フォルダのサイズを返します。

1
duggu

内部ストレージのディレクトリサイズをMediaStoreに照会できます。これは、ディレクトリ内の各ファイルの長さを取得する再帰的な方法よりもはるかに高速です。絶対必要です READ_EXTERNAL_STORAGE許可が付与されました。

例:

/**
 * Query the media store for a directory size
 *
 * @param context
 *     the application context
 * @param file
 *     the directory on primary storage
 * @return the size of the directory
 */
public static long getFolderSize(Context context, File file) {
  File directory = readlink(file); // resolve symlinks to internal storage
  String path = directory.getAbsolutePath();
  Cursor cursor = null;
  long size = 0;
  try {
    cursor = context.getContentResolver().query(MediaStore.Files.getContentUri("external"),
        new String[]{MediaStore.MediaColumns.SIZE},
        MediaStore.MediaColumns.DATA + " LIKE ?",
        new String[]{path + "/%/%"},
        null);
    if (cursor != null && cursor.moveToFirst()) {
      do {
        size += cursor.getLong(0);
      } while (cursor.moveToNext());
    }
  } finally {
    if (cursor != null) {
      cursor.close();
    }
  }
  return size;
}

/**
 * Canonicalize by following all symlinks. Same as "readlink -f file".
 *
 * @param file
 *     a {@link File}
 * @return The absolute canonical file
 */
public static File readlink(File file) {
  File f;
  try {
    f = file.getCanonicalFile();
  } catch (IOException e) {
    return file;
  }
  if (f.getAbsolutePath().equals(file.getAbsolutePath())) {
    return f;
  }
  return readlink(f);
}

使用法:

File DCIM = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
long directorySize = getFolderSize(context, DCIM);
String formattedSize = Formatter.formatFileSize(context, directorySize);
System.out.println(DCIM + " " + formattedSize);

出力:

/ storage/emulated/0/DCIM 30.86 MB

0
Jared Rummler

すべてのファイルを反復処理することは5行未満のコードであり、これを行う唯一の合理的な方法です。醜くしたい場合は、システムコマンド(Runtime.getRuntime()。exec( "du");)を実行して、出力をキャッチすることもできます;)

0
Maurits Rijk