Android数据存储方式File
Internal Storage VS External Storage
在使用File存储App数据时,我们需要了解Android系统的存储系统。Android的存储分为内部存储和外部存储。
所有的Android设备都有两块存储区域:Internal Storage和External Storage。它们的名称来源于早期的Android系统,那时候大家的手机都内置(Permanent)一块较小存储板(即Internal Storage),并配上一个的外置的(Removable)储存卡(即External Storage)。后来部分手机开始将最初定义的“Internal Storage”,即内置存储,分成Internal和External两部分。这样一来就算没有外置储存,手机也有Internal和External两块存储区域。(引用自博文,Android存储挖坑记)
Internal Storage
- /data/data/package name/files
- /data/data/package name/cache
- /data/data/package name/databases
- /data/data/package name/shared_prefs
External Storage
由于Android系统的厂商比较多,对于外部存储目录的定义有所不同,可能在根目录下的mnt,sdcard和storage下。以storage为例,打开emulated/0目录,外部存储目录就出现了。虽然可以通过多种路径打开外部存储文件,但是最终他们的路径是相同的:
External Storage path.pngmnt:
External Storage mnt.pngstorage:
External Storage.pngsdcard:
External Storage sdcard.png
外部存储目录下包含两大类:公有目录和私有目录
- 公有目录:包括九大系统创建的文件夹:Download,DICM之类的
- 私有目录:路径为/Android/data/package name/。这里包含了上述的九大文件和cache文件。
私有目录:
External Storage Private.png对比项 | Internal Storage | External Storage |
---|---|---|
可信度 | 永远可用(Permanent) | 可能不可用,最典型的当设备作为USB存储被mount时不可用 |
访问权限 | App存储内容仅App本身(或共享uid的App)可访问(Root除外) | App存储内容全局可读 |
内容持久 | App存储内容随App卸载而消失 | 当App卸载时,只有存在Android/data/package name/路径下的文件会消失 |
适用情况 | 存储内容仅App自己访问时的最佳选择 | 存储内容希望与其他App共享或传到电脑上,但是不想申请任何权限时的最佳选择 |
引用自博文,Android存储挖坑记
对比下来External有以下几点优点:
- 通过USB可以将数据传到电脑上
- 可以与其他App共享数据
- 在Android/data/package name/路径以外的数据不会因为程序卸载而被删除
缺点:
- 外置存储有时不可用
- 在非root情况下,数据无法私有化
- 在Android/data/package name/路径以外存储数据需要申请写入权限
存储权限申请
内部存储与外部存储权限申请对比如下:
Android版本 | Internal Storage | External Storage |
---|---|---|
4.4以下 | 无需权限 | 需要申请WRITE_EXTERNAL_STORAGE |
4.4及以上 | 无需权限 | 除了Android/data/package name/目录下,都需要申请WRITE_EXTERNAL_STORAGE |
注意:目前,所有App都可以读External存储而不需要任何权限,这一点可能会在未来做出改变。如果你希望读External存储,那最好申请一下READ_EXTERNAL_STORAGE权限。另外,写权限已经默认包含了读权限了。
Internal Storage存储数据
- Android数据存储之File方法getFilesDir()和openFileOutput(String name)返回的路径相同
- Android数据存储之SharedPreferences
- Databases
- Content Provider
External Storage存储数据
首先我们要获取外部存储目标文件的路径:
目标目录 | 获取方法 |
---|---|
公有目录九大文件 | Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) |
公有根目录 | Environment.getExternalStorageDirectory() |
私有目录file | Context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) |
私有目录cache | Context.getExternalCacheDir() |
然后确定自己需要创建的文件名,结合上面的到的路径,创建一个File对象:
private void saveExternal(String str) {
FileOutputStream outputStream = null;
DataOutputStream out = null;
try{
try{
outputStream = new FileOutputStream(
new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS),
"data_external.dat"));
out = new DataOutputStream(new BufferedOutputStream(outputStream));
out.writeUTF(str);
}finally {
out.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
上述表格中的方法,有两个方法需要传入一个String类型的参数,这个参数我们使用了Environment中的常量,参数的意思是我们要访问这个路径下的哪个文件夹。
App数据清理
Android系统默认数据清理的路径是,内部存储目录中相应的cache文件夹中的文件和外部存储中相应的cache文件夹中的文件。
细节
内部存储
你的app的internal storage 目录是以你的app的包名作为标识存放在Android文件系统的特定目录下[data/data/com.example.xx]。 从技术上讲,如果你设置文件为可读的,那么其他app就可以读取你的internal文件。然而,其他app需要知道你的包名与文件名。若是你没有设置为可读或者可写,其他app是没有办法读写的。因此只要你使用MODE_PRIVATE ,那么这些文件就不可能被其他app所访问。
另外记住一点,内部存储在你的APP卸载的时候,会一块被删除,因此,我们可以在cache目录里面放置我们的图片缓存,而且cache与files的差别在于,如果手机的内部存储空间不够了,会自行选择cache目录进行删除,因此,不要把重要的文件放在cache文件里面,可以放置在files里面,因为这个文件只有在APP被卸载的时候才会被删除。还有要注意的一点是,如果应用程序是更新操作,内部存储不会被删除,区别于被用户手动卸载。
外部存储
不管你是使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,还是使用 getExternalFilesDir() 来储存那些对于你的app来说是私有的文件,有一点很重要,那就是你要使用那些类似DIRECTORY_PICTURES 的API的常量。那些目录类型参数可以确保那些文件被系统正确的对待。例如,那些以DIRECTORY_RINGTONES 类型保存的文件就会被系统的media scanner认为是ringtone而不是音乐。
清除数据、清除缓存的区别
- 清除数据主要是清除用户配置,比如SharedPreferences、数据库等等,这些数据都是在程序运行过程中保存的用户配置信息,清除数据后,下次进入程序就和第一次进入程序时一样
- 缓存是程序运行时的临时存储空间,它可以存放从网络下载的临时图片,从用户的角度出发清除缓存对用户并没有太大的影响,但是清除缓存后用户再次使用该APP时,由于本地缓存已经被清理,所有的数据需要重新从网络上获取。为了在清除缓存的时候能够正常清除与应用相关的缓存,请将缓存文件存放在getCacheDir()或者 getExternalCacheDir()路径下。
总结
在开发中,不建议往内部存储中写太多的数据,毕竟空间有限。外部存储在使用的时候最好能够将文件存放在私有目录下,这样有利于系统维护,也避免用户的反感。
网友评论