是否可以轻松获取 SD 卡上文件夹的大小?我使用一个文件夹来缓存图像,并希望显示所有缓存图像的总大小。除了遍历每个文件之外,还有其他方法吗?它们都驻留在同一个文件夹中?
11 回答
只需浏览所有文件并总结它们的长度:
/**
* Return the size of a directory in bytes
*/
private static long dirSize(File dir) {
if (dir.exists()) {
long result = 0;
File[] fileList = dir.listFiles();
if (fileList != null) {
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;
}
注意:手工编写的函数,因此无法编译!
这是一些避免递归的代码,并且还计算物理大小而不是逻辑大小:
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;
}
/**
* 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;
}
你应该使用这个代码:
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;
}
其他解决方案的问题是它们只为您提供指定目录中所有文件的逻辑大小。它将与实际(物理)使用空间不同。如果您的目录有很多子目录和/或小文件,则目录的逻辑大小和实际大小之间可能存在巨大差异。
这是我发现的如何计算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);
}
#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;
}
您可以查询 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
下面的方法返回你的文件夹大小: -
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);
返回文件夹的大小。
希望这可以帮助
导入这个
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);
}
Iterating through all files is less than 5 lines of code and the only reasonable way to do this. If you want to get ugly you could also run a system command (Runtime.getRuntime().exec("du");) and catch the output ;)
这是 Linh Toòng 的回答中的一个片段,还有一些检查(主要是为了阻止 Android Studio 的警告!)
private long getFolderSize(File file) {
if (file == null || !file.exists())
return 0;
long size = 0;
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files == null || files.length == 0)
return size;
for (File f : files)
size += getFolderSize(f);
} else
size += file.length();
return size;
}