¿Es posible obtener fácilmente el tamaño de una carpeta en la tarjeta SD? Utilizo una carpeta para el almacenamiento en caché de imágenes y me gustaría presentar el tamaño total de todas las imágenes en caché. ¿Hay alguna forma de hacerlo que no sea iterar sobre cada archivo? ¿Todos residen dentro de la misma carpeta?¿Cómo puedo obtener el tamaño de una carpeta en la tarjeta SD en Android?
Respuesta
Sólo tienes que ir a través de todos los archivos y la suma de la longitud de ellos:
/**
* 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;
}
NOTA: Función escrito a mano por lo que no podría compilar!
EDITADO: llamada recursiva fija.
EDITADO: dirList.length cambiado a fileList.length.
Iterar a través de todos los archivos es menos de 5 líneas de código y la única forma razonable de hacerlo. Si desea ponerse feo también se puede ejecutar un comando del sistema (Runtime.getRuntime() exec ("du");.) Y coger la salida;)
Lo suficiente. Pensé que era un caso de uso tan común que debería haber alguna solución nativa. La pereza es buena ... Cinco líneas después, y estoy feliz :) –
En Clojure: (defn dir-size [dir] (reduce + (map # (. Length%) (.listFiles (nuevo File dir))))) –
No creo que sea seguro confiar en que esté disponible y ejecutable. –
/**
* 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;
}
Como estamos hablando de operaciones de archivos, es poco probable que la recursividad represente gran parte del rendimiento alcanzado. Además, la implementación de java.util.Stack es muy lenta. Traté de optimizar un algoritmo recursivo con él y en realidad fue más lento que dejar que la JVM hiciera su trabajo. –
java.util.Los métodos de clase de pila están sincronizados. Si realmente desea evitar la recursividad, es mejor utilizar LinkedList. –
debajo método retorno que el tamaño de la carpeta: -
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;
}
llamada anterior método: -
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/urfoldername/");
long folder_size=getFolderSize(file);
que regreso tamaño de la carpeta.
El camino de #Moss es correcto. Este es mi código para aquellos que quieren cambiar los bytes a un formato legible por humanos. Sólo tiene que asignar ruta de la carpeta para dirSize(String path)
y obtener formato legible por humanos basado en bytes, kilo, mega y etc
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;
}
Problema con otra solución es que te proporcionan solamente tamaño lógico de todos los archivos especificados directorio. Será diferente del espacio utilizado real (físico). Si su directorio tiene muchos subdirectorios y/o archivos pequeños, puede haber una gran diferencia entre el tamaño lógico y el tamaño real del directorio.
Esto es lo que encontré cómo tener en cuenta la estructura física de 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;
}
}
Puede utilizar StatFs
para obtener el tamaño de bloque:
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);
}
Me he dado cuenta de que si llamo "length()" en un directorio, no obtengo 0, sino un número real. ¿Es posible que en lugar de usar lo que has hecho, simplemente puedas usar "length()" en los directorios (y por supuesto, hacer el resto, agregar el tamaño de los archivos normales)? –
se debe utilizar este código:
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;
}
¡Gran solución para mí, tengo una carpeta con algunos archivos de audio y funciona perfectamente para mí! (No tengo ninguna subcarpeta en esta carpeta!) – basti12354
Aquí hay un código que evite la repetición, y también calcula el tamaño físico vez del tamaño lógico:
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;
}
esta es la respuesta correcta para calcular el tamaño de ARCHIVO/CARPETA –
De hecho, me sorprendió ver que (en Android) cada carpeta tarda unos 4 KB incluso cuando está vacía. Me pregunto por qué lo hicieron de esta manera. –
@androiddeveloper Es el tamaño del sector. Notarás que lo mismo es cierto en cualquier sistema operativo de escritorio. –
Puede consultar MediaStore para obtener un tamaño de directorio en el almacenamiento interno. Esto es mucho más rápido que un método recursivo para obtener la longitud de cada archivo en un directorio. Debe tener el permiso READ_EXTERNAL_STORAGE
otorgado.
Ejemplo:
/**
* 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);
}
Uso:
File DCIM = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
long directorySize = getFolderSize(context, DCIM);
String formattedSize = Formatter.formatFileSize(context, directorySize);
System.out.println(DCIM + " " + formattedSize);
de salida:
/almacenamiento/emulado/0/DCIM 30,86 MB
- 1. Eliminar una carpeta en la tarjeta SD
- 2. Cómo crear una carpeta privada en una tarjeta SD
- 3. Android Guardar imagen en la tarjeta SD
- 4. escritura Android para carpeta de la tarjeta SD
- 5. ¿Cómo abrir la carpeta de la tarjeta SD en Android AVD?
- 6. Cómo verificar si la carpeta recién creada está presente en la tarjeta SD en Android
- 7. Cómo puedo leer el archivo json de la tarjeta SD
- 8. cómo obtener los nombres de archivo almacenados en la tarjeta SD en Android
- 9. Uso de la cámara sin tarjeta SD en Android
- 10. ¿Cómo saber si la tarjeta SD está montada en Android?
- 11. Cómo guardar archivos en la tarjeta SD
- 12. android obtener una miniatura de la imagen almacenada en una tarjeta SD cuya ruta se conoce
- 13. Compruebe si existe archivo en la tarjeta SD en Android
- 14. obtener transmisión recibida cuando la tarjeta SD está desmontando android
- 15. Permiso para escribir en la tarjeta SD
- 16. Comprobar si existe directorio en la tarjeta SD de Android
- 17. Android - eliminar archivos en la tarjeta SD al desinstalar
- 18. Almacenamiento de datos en la tarjeta SD en Android
- 19. Android: eliminar una imagen de la tarjeta SD
- 20. Servicio de reinicio para la aplicación en la tarjeta SD Cuando se repone la tarjeta SD
- 21. Características de la tarjeta SD Android en Samsung Galaxy
- 22. ¿Cómo puedo escuchar el montaje de la tarjeta SD en Android?
- 23. cómo obtener la ruta del archivo de la tarjeta SD en Android
- 24. imágenes en la tarjeta SD de acceso
- 25. Escribiendo a la tarjeta SD
- 26. ¿Cómo leer el número de ID de la tarjeta SD?
- 27. Android 2.2 - ¿Cómo puedo detectar si estoy instalado en la tarjeta SD o no?
- 28. ¿Cómo puedo hacer una copia de seguridad del archivo sqlite en la tarjeta SD mediante programación?
- 29. android leyendo una imagen de la tarjeta SD
- 30. Escribiendo un archivo en una tarjeta SD
Es posible que desee reemplazar findFile por dirSize :) –
sugiero reemplazar 'dir.exists()' con 'dir.isDirectory()'. si un archivo se da como argumento, se lanza NullPointerException debido al resultado de listFiles(). –
@Moss El ciclo "para-cada uno" es mejor, como Google sugiere en http://developer.android.com/training/articles/perf-tips.html#Loops –