Android数据存储之File总结

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
Internal Storage.png

External Storage

由于Android系统的厂商比较多,对于外部存储目录的定义有所不同,可能在根目录下的mnt,sdcard和storage下。以storage为例,打开emulated/0目录,外部存储目录就出现了。虽然可以通过多种路径打开外部存储文件,但是最终他们的路径是相同的:

External Storage path.png

mnt:

External Storage mnt.png

storage:

External Storage.png

sdcard:


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存储数据

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()路径下。

总结

在开发中,不建议往内部存储中写太多的数据,毕竟空间有限。外部存储在使用的时候最好能够将文件存放在私有目录下,这样有利于系统维护,也避免用户的反感。

参考

彻底理解android中的内部存储与外部存储

Android存储挖坑记

缓存文件可以放在哪里?它们各自的特点是什么

推荐阅读更多精彩内容