Android 文件存储浅析

最近做的一个需求和文件存储有关系。由于之前没有系统梳理过,对文件存储方面的知识一直很懵懂。趁着周末有时间,赶快梳理一波。

这首从网上找到的一张图,很好的归纳综合了外部存储和内部存储。

Android 文件存储浅析

 

下面我们再来详细先容相关知识和内容。

内部存储 

内部存储,位于data/data/包名/路径下

是否需要用户权限:否

是否能被其他应用接见:否

卸载应用数据是否被删除:是

内部存储控件不需要用户权限,这意味着我们不需要用户去授权下面的权限:

android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAGE

对于装备中每一个安装的 App,系统都会在 data/data 目录下以应用程序包名自动建立与之对应的文件夹,可以直接读写该目录下的文件。而且该目录下的文件不能被其他应用接见。这也就保证了我们应用内部存储的文件的安全性和隐私性,若是我们需要查看自己应用内部的文件,我们可以通过 Android Studio的Device File Explore 工具举行接见:

Android 文件存储浅析   
Android 文件存储浅析

 

通过这个,可以查看对应应用的存储文件。

/data/data/应用名/cache :存放的是APP的缓存信息

/data/data/应用名/code_cache :在运行时存放应用发生的编译或者优化的代码

/data/data/应用名/files : 存放APP的文件信息

另有一些运行时,发生的文件夹,例如挪用 SharedPreference 所发生的 /data/data/应用包名/shared_prefs 目录,存放着 app 的 SharedPreference 所发生的 xml 文件,另有挪用数据库所发生的 **/data/data/应用包名/databases/** 文件夹,这里就不逐一举例。

从技术上来讲若是你在建立内部存储文件的时刻将文件属性设置成可读,其他 app 能够接见自己应用的数据,条件是他知道你这个应用的包名,若是一个文件的属性是私有(private),那么纵然知道包名其他应用也无法接见。 内部存储空间十分有限,因而显得难得,另外,它也是系统自己和系统应用程序主要的数据存储所在地,一旦内部存储空间耗尽,手机也就无法使用了。以是对于内部存储空间,我们要只管制止使用。Shared Preferences 和 SQLite 数据库都是存储在内部存储空间上的。内部存储一样平常用 Context 来获取和操作。
接见内部存储的API方式:

  1. getFilesDir().getAbsolutePath()  : /data/user/0/com.example.myapplication/files

  2. getCacheDir().getAbsolutePath() :  /storage/emulated/0/Android/data/com.example.myapplication/cache

  3. getDir(“myFile”, MODE_PRIVATE).getAbsolutePath()  : /data/user/0/com.example.myapplication/app_myfile

  4. getCodeCacheDir().getAbsolutePath() : /data/user/0/com.example.myapplication/code_cache  ,要求Android5.0+

外部存储

观点:最容易混淆的是外部存储,由于老的 Android 系统的跟新的 Android 系统是有差异的,许多人去网上查找资料,看了一下以前的资料,又看了一下现在的资料,然则发现它们说法不一样然后就疑心了。

首先说一个人人普遍的观点 “若是在 pc 机上是区分外部存储和内部存储的话,那么电脑自带的硬盘算是内部存储,U盘或者移动硬盘就是外部存储了。” 因此许多人带着这样的明白去看待安卓手机,把内置存储(机身存储)当做内部存储,而把扩展的 SD 卡当做是外部存储。

前端程序员学好算法系列(二)数组

这么以为确实没错,由于在 4.4(API19)以前的手机上确实是这样的,手机自身带的存储卡就是内部存储,而扩展的SD卡就是外部存储。

然则从 4.4 的系统最先,许多的中高端机械都将自己的机身存储扩展到了 8G 以上,好比有的人的手机是 16G 的,有的人的手机是 32G 的,然则这个 16G,32G 是内部存储吗,不是的,它们依然是外部存储。

也就是说 4.4 系统及以上的手机将机身存储存储(手机自身带的存储叫做机身存储)在观点上分成了 “内部存储internal” 和 “外部存储external” 两部分。既然 16G,32G 是外部存储,那有人又有疑惑了,那 4.4 系统及以上的手机要是插了 SD 卡呢,SD 卡又是什么呢,若是 SD 卡也是外部存储的话,那怎么区分机身存储的外部存储跟 SD 卡的外部存储呢?

对,SD卡也是外部存储,那怎么区分呢,在4.4以后的系统中,API提供了这样一个方式来遍历手机的外部存储路径:

File[] files;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    files = getExternalFilesDirs(Environment.MEDIA_MOUNTED);
    for(File file:files){
        Log.e("main",file);
    }
}

若是你的手机插了SD卡的话,那么它打印的路径就有两条了,例如我的华为荣耀 7 插了SD卡,它的效果如下:

/storage/emulated/0/Android/data/packname/files/mounted
/storage/B3E4-1711/Android/data/packname/files/mounted

其中 /storage/emulated/0 目录就是机身存储的外部存储路径,而 /storage/B3E4-1711/ 就是 SD 卡的路径,他们统称为外部存储。

一样平常对于外部存储可以分为两类,外部公有和外部私有。

外部公有

是否需要用户权限:

是否能被其他应用接见:

卸载应用数据是否被删除:

公共目录必须需要用户授权读写的权限,这意味着我们需要在 AndroidManifest.xml 中注册用户权限。

    <!-- 外部存储写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

而且在 Android 6.0 系统之后需要申请用户权限,并获得用户授权,才气读写文件。

公共目录相对开放,我们可以接见其他APP存在公共目录下的文件,而且当 APP 被删除时,并不会删除应用存在公共目录下的文件。

我们可以通过 Environment 工具,接见读写公共目录的文件。

在对外部存储举行读写的时刻,应该先判断一下外部存储的状态,是否能够支持读写。

Environment.getExternalStorageState() 
/**       {@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}
 */

只有在返回值为 MEDIA_MOUNTED 示意当前是可正常读写的。

接下来让我们看看相关的API。

1. Environment.getExternalStorageDirectory() : /storage/emulated/0

2. Environment.getExternalStoragePublicDirectory(String type)  
       Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath()  : /storage/emulated/0/Documents
    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getAbsolutePath() : /storage/emulated/0/Music

外部私有

是否需要用户权限:4.4以上不需要

是否能被其他应用接见:否

卸载应用数据是否被删除:是

私有目录,在 Android4.4 系统以上。不需要注册和用户授权外部私有存储的读写的权限,就可以在应用的外部私有举行读写文件。而且文件不能被其他应用所接见,具有较好的隐私性和安全性,而且在用户删除的时刻,对应的应用私有目录也会被删除。

私有目录地址:/storage/emulated/0/Android/data/应用包名

相关API如下:

getExternalCacheDir().getAbsolutePath()  // /storage/emulated/0/Android/data/com.example.myapplication/cache

getExternalFilesDir("mytest").getAbsolutePath() // /storage/emulated/0/Android/data/com.example.myapplication/files/mytest
getExternalFilesDir(null).getAbsolutePath()  // /storage/emulated/0/Android/data/com.example.myapplication/files

总结

本文详细先容了 android 的外部存储和私有存储。人人在有保留文件的需求的时刻,凭据自己的需要,选择到底是存在那里对照合适。内部存储相对较小,不介意把一些大文件存在其中。应该存在外部存储会更好。对于可以给其他文件接见的,可以存在外部存储的公有文件内里。

 

参考文献

快速明白Android文件存储路径

彻底搞懂Android文件存储—内部存储,外部存储以及种种存储路径解惑

原创文章,作者:admin,如若转载,请注明出处:https://www.2lxm.com/archives/25167.html