Как узнать размер папки на SD-карте в Android? - PullRequest
27 голосов
/ 28 октября 2010

Можно ли легко получить размер папки на SD-карте?Я использую папку для кэширования изображений и хотел бы представить общий размер всех кэшированных изображений.Есть ли способ, кроме как перебирать каждый файл?Все они находятся в одной папке?

Ответы [ 10 ]

39 голосов
/ 28 октября 2010

Просто просмотрите все файлы и суммируйте их длину:

/**
 * 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.

14 голосов
/ 03 мая 2014

Вот некоторый код, который избегает рекурсии, а также вычисляет физический размер вместо логического размера:

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;
}
5 голосов
/ 27 марта 2014

Вы должны использовать этот код:

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 голосов
/ 10 марта 2011
/**
 * 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;
}
3 голосов
/ 25 октября 2013

Проблема с другим решением состоит в том, что они предоставляют вам только логический размер всех файлов в указанном каталоге.Это будет отличаться от фактического (физического) используемого пространства.Если в вашем каталоге много подкаталогов и / или небольших файлов, между логическим и фактическим размером каталога может быть огромная разница.

Вот то, что я нашел, как определить физическую структуру 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 голосов
/ 19 июня 2013

Путь # Мосс правильный.Это мой код для тех, кто хочет изменить байты в удобочитаемый формат.Вам просто нужно назначить путь к вашей папке на 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;
    } 
1 голос
/ 24 марта 2013

ниже метода вернет вам размер папки: -

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

верните вам размер папки.

0 голосов
/ 29 января 2019

Надеюсь, это поможет

импортировать это

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);
    }
0 голосов
/ 11 февраля 2017

Вы можете запросить 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);

Выход:

/ хранилище / эмуляция / 0 / DCIM 30,86 МБ

0 голосов
/ 28 октября 2010

Итерация по всем файлам - это менее 5 строк кода и единственный разумный способ сделать это.Если вы хотите выглядеть ужасно, вы также можете запустить системную команду (Runtime.getRuntime (). Exec ("du");) и перехватить вывод;)

...