studio - manual de programacion android pdf
¿Cómo puedo obtener el tamaño de una carpeta en la tarjeta SD en Android? (9)
¿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 almacenadas en caché. ¿Hay alguna otra forma de iterar sobre cada archivo? ¿Todos residen dentro de la misma carpeta?
Aquí hay algo de código que evita la recursión y también calcula el tamaño físico en lugar 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;
}
Debes usar 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;
}
El camino de #Moss es correcto. Este es mi código para aquellos que quieren cambiar bytes a formato legible por humanos. Solo debe asignar la ruta de su carpeta a dirSize(String path)
y obtener un formato legible para el ser humano basado en byte, 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;
}
El método a continuación le devuelve 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;
}
Llame al método de arriba:
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/urfoldername/");
long folder_size=getFolderSize(file);
Vuelve tu tamaño de carpeta.
El problema con otra solución es que le proporcionan solo el tamaño lógico de todos los archivos en el directorio especificado. 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 real del directorio.
Aquí es lo que encontré cómo tomar 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;
}
}
Puedes usar 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);
}
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 puede ejecutar un comando del sistema (Runtime.getRuntime (). Exec ("du");) y capturar la salida;)
Puede consultar MediaStore para un tamaño de directorio en el almacenamiento interno. Esto es mucho más rápido que un método recursivo que obtiene la longitud de cada archivo en un directorio. Debe tener permiso READ_EXTERNAL_STORAGE
concedido.
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);
Salida:
/ almacenamiento / emulado / 0 / DCIM 30.86 MB
Simplemente vaya a través de todos los archivos y sume 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 escrita a mano para que no se compile!
EDITADO: llamada recursiva fija.
EDITADO: dirList.length cambiado a fileList.length.
/**
* 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;
}