一、StatFs 计算Sdcard磁盘容量
public static long getSDAvailableSpace(){
String state = Environment.getExternalStorageState();
long size = 0;
if(Environment.MEDIA_MOUNTED.equals(state)) {
File sdcardDir = Environment.getExternalStorageDirectory();
StatFs sf = new StatFs(sdcardDir.getPath());
long blockSize = sf.getBlockSizeLong();
// long blockCount = sf.getBlockCount();
long availCount = sf.getAvailableBlocksLong();
size = blockSize*availCount;
}
return size;
}
二、利用 递归计算 某个文件夹的文件大小
public static double getFileOrFilesSize(String path){
return getFileOrFilesSize(path,SIZETYPE_B);
}
/**
* 获取文件指定文件的指定单位的大小
*
* @param filePath 文件路径
* @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
* @return double值的大小
*/
public static double getFileOrFilesSize(String filePath, int sizeType) {
File file = new File(filePath);
long blockSize = 0;
if(!file.exists()){
blockSize = 0;
return blockSize;
}
try {
if (file.isDirectory()) {
blockSize = getFileSizes(file);
} else {
blockSize = getFileSize(file);
}
} catch (Exception e) {
e.printStackTrace();
LogUtil.d(TAG,"获取文件大小失败!");
}finally {
}
return FormetFileSize(blockSize, sizeType);
}
/**
* 转换文件大小,指定转换的类型
*
* @param fileS
* @param sizeType
* @return
*/
private static double FormetFileSize(long fileS, int sizeType) {
DecimalFormat df = new DecimalFormat("#.00");
double fileSizeLong = 0;
switch (sizeType) {
case SIZETYPE_B:
fileSizeLong = Double.valueOf(df.format((double) fileS));
break;
case SIZETYPE_KB:
fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
break;
case SIZETYPE_MB:
fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
break;
case SIZETYPE_GB:
fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824));
break;
default:
break;
}
return fileSizeLong;
}
/**
* 获取指定文件夹
*
* @param f
* @return
* @throws Exception
*/
private static long getFileSizes(File f) throws Exception {
long size = 0;
File flist[] = f.listFiles();
for (int i = 0; i < flist.length; i++) {
if (flist[i].isDirectory()) {
size = size + getFileSizes(flist[i]);
} else {
size = size + getFileSize(flist[i]);
}
}
return size;
}
/**
* 获取指定文件大小
*
* @param file
* @return
* @throws Exception
*/
private static long getFileSize(File file) throws Exception {
long size = 0;
if (file.exists()) {
FileInputStream fis = null;
fis = new FileInputStream(file);
size = fis.available();
fis.close();
// Log.d(TAG,"getFileSize:"+file.getPath()+",size:"+size);
} else {
// file.createNewFile();
LogUtil.d(TAG,"获取文件大小不存在!");
}
return size;
}
三、删除文件后,磁盘可用容量没有减小的问题
在Linux中,当我们使用rm在linux上删除了大文件,但是如果有进程打开了这个大文件,却没有关闭这个文件的句柄,那么linux内核还是不会释放这个文件的磁盘空间。
通过rm或者文件管理器删除文件,只是将它会从文件系统的目录结构上解除链接(unlink),也就是说只是删除了文件和系统目录结构的链接;如果文件在删除时是被打开的(有一个进程正在使用该文件,文件被进程锁定或者有进程一直在向这个文件写数据等)状态,那么进程将仍然可以读取该文件,也就是说没有删除掉文件在读取的状态,所以磁盘空间也就会一直被占用。
一个文件在文件系统中的存放分为两个部分:数据部分和指针部分,指针位于文件系统的meta-data中,数据被删除后,这个指针就从meta-data中清除了,而数据部分存储在磁盘中,数据对应的指针从meta-data中清除后,文件数据部分占用的空间就可以被覆盖并写入新的内容,之所以出现删除文件后,空间还没释放,就是因为有进程还在一直向这个文件写入内容,导致虽然删除了文件,但文件对应的指针部分由于进程锁定,并未从meta-data中清除,而由于指针并未被删除,那么系统内核就认为文件并未被删除,因此通过df命令查询空间并未释放也就不足为奇了。
lsof 全名 list open files - 用于显示已经打开的文件。
lsof | grep deleted |grep 文件名
- 上述命令,可以用来帮助查看 哪些文件处于打开状态,但是文件内容却已经被删除了。
- lsof 需要在超级用户下运行
rk3399_mid:/ $ su
rk3399_mid:/ # lsof | grep deleted
init 1 root 3w CHR 1,11 0t0 253 /dev/__kmsg__ (deleted)
ueventd 184 root 3w CHR 1,11 0t0 2714 /dev/__kmsg__ (deleted)
main 328 root mem unknown /dev/ashmem/dalvik-main space (deleted)
main 328 root mem unknown /dev/ashmem/dalvik-main space 1 (deleted)
网友评论