android文件系统管理全解析——内部存储和外部存储 /data/data和/sdcard/Android/data区别

文件系统是android一个重要的部分。我们需要保存app的一些数据。或者我们需要用到系统的一些数据,如相册等。那么就需要对文件系统有一定的了解。
android文件系统有一个非常让人困惑的地方,就是获取的文件名和路径可能是不确定的。例如下面的代码,这个代码是非常常用的。但这个代码在不同的android版本可能出现的结果不同。

Environment.getExternalStorageDirectory()

可能出现下面的结果。

/storage/emulated/0
/mnt/sdcard
/storage/sdcard

storage和sdcard的区别

这里有一个非常困惑的问题,就是storage和sdcard有什么区别?在SDK19(android4.4)开始,android系统就封禁了sd卡。转而变成了内置sd卡(不可简单更换),或者叫内部存储器也行。原因也非常的简单,因为允许用户自己换sd卡似乎不太安全。sd卡五花八门,对系统兼容性和稳定性都有非常大的影响。换成内置也是理所当然。
如下面SDK16的文件目录,/sdcard(root目录下)链接的地址实际上是/mmt/sdcard(注意看sdcard文件夹有个箭头的小图标,表示是软链接)。虽然也有/storage目录,但/storage是个空目录。

在这里插入图片描述
在这里插入图片描述

再看看SDK19的目录结构,就看出了明显不同。/sdcard链接的是/storage/sdcard,这里并没有直接删除/sdcard,而是改了链接的目标地址,可能也是考虑兼容性问题吧。
在这里插入图片描述
值得一提的是/mnt/sdcard实际上也是链接到了/storage/sdcard
在这里插入图片描述
对于开发者来说,不需要关系getExternalStorageDirectory()获取到的到底是那个目录,我们更关心的无非是他的子目录,也就是下面这些常见目录。

在这里插入图片描述

外部存储和内部存储

现在要说说什么是外部存储和内部存储。其实这两个概念非常的简单,/data/data目录下的空间就是内部存储。在getExternalStorageDirectory方法的文档也有说明,外部的同义词是share(共享)。例如/sdcard/Android/data,注意,这里有个容易混淆的地方。不管是sd卡还是内部存储卡,其实都是外部存储(外部存储和内部存储并不是物理概念,而是目录的功能概念)。外部存储的一个最大的特定就是共享,别的应用都能修改你的app的存储在外部存储的数据。也就是外部数据是不安全的。
总的来说,外部存储是对于app共享的,内部存储对于app是独占的。

/data/data和/sdcard/Android/data目录的共同点和区别

共同点:
app被卸载的时候/sdcard/Android/data和/data/data的数据会被清除。(一定要刷新(Synchronize)文件系统!!!点开关闭是没有用的,并且Synchronize只能刷新当前文件夹,换了一个文件夹需要重新刷新)
在这里插入图片描述

从上面的文件结构可以发现,这两个目录下都可以存放app的数据,那么这两个文件有什么区别呢?
区别:
1./sdcard/Android/data属于外部存储。/data/data属于内部存储。
2…别的app能修改/sdcard/Android/data下其它app的数据。别的app不能修改/data/data目录下不是自己的数据。

Context提供的文件操作方法

内部存储操作方法

主要有getCacheDir(),getFilesDir()和getCodeCacheDir(), getSharedPreferences()

接下来要介绍三个Context的方法。这三个方法都是对于内部存储的,也就是/data/data目录。非常有意思的是,这三个方法都是不需要读写权限的,也不需要在清单文件中声明权限,因为app私有目录本身就已经有读写权限了。
getCacheDir():
获取/data/data/app包名/cache文件夹,默认已经存在。在这个文件夹下面的读写操作都不需要申请读写权限,因为默认已经有了。
getFilesDir():
获取/data/data/app包名/files文件夹,默认已经存在。在这个文件夹下面的读写操作都不需要申请读写权限,因为默认已经有了。
getCodeCacheDir():
SDK21才有的方法。获取/data/data/app包名/code_cache文件夹,没有会创建。在这个文件夹下面的读写操作都不需要申请读写权限,因为默认已经有了。
getSharedPreferences():
SharedPreferences我们非常熟悉。所产生的文件在/data/data/shared_prefs目录下,没有会创建,不需要读写权限。
getDataDir():
获取/data/app/app包名 目录。需要SDK24,并且需要root权限,一般是用不到的。
getObbDir:
获取/sdcard/Android/obb/app包名。需要读写权限。

外部存储操作方法

和内部存储操作方法非常类似,只是这些方法都是在/sdcard/Android/data目录下,在这些目录下面的读写操作是需要读写权限的,但是调用这些方法本身不需要读写权限。
getExternalCacheDir():
读取/sdcard/Android/data/app包名/cache目录。没有创建。卸载删除。
getExternalCacheDirs():
和getExternalCacheDir相比,可以返回多个sd卡的/sdcard/Android/data/app包名/cache目录,不过这种情况不常见。而且需要最少SDK19。
getExternalFilesDir(String type):
这个方法非常的有用。可以传一个type参数对应下面的目录文件名。例如Environment.DIRECTORY_DCIM。表示DCIM这个目录,也就是相册目录。
在这里插入图片描述
getExternalFilesDirs(String type):
同getExternalFilesDir(String type),只是可以返回多个sd卡的内容。需要SDK19。

getExternalMediaDirs():
返回sdcard/Android/data/app包名/media目录。需要SDK21一般用不到。

Environment提供的获取目录方法

Environment类也提供了几个获取非常常用的目录的方法。
getExternalStorageDirectory:
前面已经提到,可以获取外部存储的根目录。可能有下面的结果。这个方法在android10废弃,取代的是Context的getExternalFilesDir(String type)

/storage/emulated/0
/mnt/sdcard
/storage/sdcard

getExternalStorageState:
获取外部存储的状态,这个方法没有跟着废弃。一般返回MOUNTED,也可能是下面的值。一般用不到。

  * @return one of {
    
    @link #MEDIA_UNKNOWN}, {
    
    @link #MEDIA_REMOVED},
     *         {
    
    @link #MEDIA_UNMOUNTED}, {
    
    @link #MEDIA_CHECKING},
     *         {
    
    @link #MEDIA_NOFS}, {
    
    @link #MEDIA_MOUNTED},
     *         {
    
    @link #MEDIA_MOUNTED_READ_ONLY}, {
    
    @link #MEDIA_SHARED},
     *         {
    
    @link #MEDIA_BAD_REMOVAL}, or {
    
    @link #MEDIA_UNMOUNTABLE}.

getRootDirectory:
返回/system目录。

getDataDirectory:
返回/data目录。
getDownloadCacheDirectory:
返回/cache目录。

猜你喜欢

转载自blog.csdn.net/ScottePerk/article/details/125707081