最近在研究图片的高效加载的时候,偶然发现一个类StatFs类,通过androidSDK的介绍了解了这个类的作用,加之最近操作系统课也在学习文件系统,顺便就研究了一下。
个人感想:其实有些东西学了原理之后真的就很好了解,不然的话真的只是在调用API.
现在开始啦:
研究它必须先知道它是什么?
Retrieve overall information about the space on a filesystem. This is a wrapper for Unix statvfs().
上面是之间从android的sdk中复制来的,简单翻译下:获得文件体统的所有空间信息,这是一个对unix中的statvfs()函数的包装。很好理解。
在开始之前我觉得还是说一个操作系统中的文件系统的相关知识比较好,毕竟不仅仅是来说API。
为了有效的管理文件存储设备,便于对文件信息进行处理,通常将文件你存储器空间划分为大小相同的逻辑块,并进行统一编号;为了便于管理,可将用户文件划分为与物理块号同样大小的逻辑块,并将块作为存储介质分配给内外存之间传输信息的基本单位。块的大小是固定的,一般为512或者1024字节。
上面内容来源于课本。说的非常的清晰,从上面的介绍我们应该知道,在文件系统中,数据的存储是在每一个逻辑块上的,对于程序员来说,我们能处理的基本单位就是块。所以如果你看android的sdk,你会发现,其提供的api主要是以块为单位进行处理的。
下面介绍一下StatFs类下的api,和使用过程中的细节。
StatFs(String path)
这是该类的构造方法,传入的是一个文件系统的路径。我们看一下具体的实现:
public StatFs(String path) {
mStat = doStat(path);
}
private static StructStatVfs doStat(String path) {
try {
return Os.statvfs(path);
} catch (ErrnoException e) {
throw new IllegalArgumentException("Invalid path: " + path, e);
}
}
其实上面只有一句有实际意义,那就是Os.statvfs(path),它本身会调用系统函数Libcore.os.statvfs(path)。这就是为什么说这个类是对unix中的statvfs()函数的包装。
-getAvailableBlocksLong()
获取文件系统中,对你的应用而言可以获得的空闲块数
-getAvailableBytes()
获取文件系统中,对你的应用而言可以获得的空闲字节数
-getBlockCountLong()
获取文件系统中,总块数
-getBlockSizeLong()
获取文件系统中,每块的大小(字节数)
-getFreeBlocksLong()
获取文件系统中,总的空闲块数,包括保留的块数(对应用而言,那是不可用的)
-getFreeBytes()
获取文件系统中,总的空闲大小(字节数),包括保留块(对应用而言,那是不可用的)
-getTotalBytes()
获取文件系统中,支持的最大字节数
-restat(String path)
通过该方法,可以改变当前所操作的路径
上面讲述了该类的一些基本信息,光说这些显得很是空洞,在网上找到一些实例,将理论与实际相结合。
获取手机内部可用空间大小
/**
* 获取手机内部可用空间大小
* @return
*/
staticpubliclong getAvailableInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
}
获取手机内部可用空间大小
/**
* 获取手机内部可用空间大小
* @return
*/
static public long getAvailableInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
}
获取手机内部空间大小
/**
* 获取手机内部空间大小
* @return
*/
staticpubliclong getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();//Gets the Android data directory
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize(); //每个block 占字节数
long totalBlocks = stat.getBlockCount(); //block总数
return totalBlocks * blockSize;
}
获取手机内部空间大小
/**
* 获取手机内部空间大小
* @return
*/
static public long getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();//Gets the Android data directory
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize(); //每个block 占字节数
long totalBlocks = stat.getBlockCount(); //block总数
return totalBlocks * blockSize;
}
获取手机外部可用空间大小
/**
* 获取手机外部可用空间大小
* @return
*/
staticpubliclong getAvailableExternalMemorySize() {
if (isExternalStorageAvailable()) {
File path = Environment.getExternalStorageDirectory();//获取SDCard根目录
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
} else {
return -1;
}
}
获取手机外部总空间大小
/**
* 获取手机外部总空间大小
* @return
*/
staticpubliclong getTotalExternalMemorySize() {
if (isExternalStorageAvailable()) {
File path = Environment.getExternalStorageDirectory(); //获取SDCard根目录
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
} else {
return -1;
}
}
获取手机外部可用空间大小
/**
* 获取手机外部可用空间大小
* @return
*/
static public long getAvailableExternalMemorySize() {
if (isExternalStorageAvailable()) {
File path = Environment.getExternalStorageDirectory();//获取SDCard根目录
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
return availableBlocks * blockSize;
} else {
return -1;
}
}
获取手机外部总空间大小
/**
* 获取手机外部总空间大小
* @return
*/
static public long getTotalExternalMemorySize() {
if (isExternalStorageAvailable()) {
File path = Environment.getExternalStorageDirectory(); //获取SDCard根目录
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
} else {
return -1;
}
}
在AndroidManifest.xml中加入访问SDCard的权限如下:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>