Android中的内部存储和外部存储

前言

Android系统的内部存储和外部存储是两个容易混淆的概念。
下面通过两个图来对内部存储和外部存储进行简单阐述。
图一:内部存储和外部存储
在这里插入图片描述
图二:Android系统目录结构
Android系统的内核使用的是Linux内核, 所以Android的文件目录结构和Linux系统的文件目录结构类似.Android系统使用虚拟文件系统(VFS), VFS的目录是以/为根节点,根节点下又有不同的节点。而我们的物理存储设备就是挂载都这些节点上,如下图所示:
在这里插入图片描述

内部存储

内部存储是指系统内部存储空间,在逻辑上用目录来区分就是data目录下的文件夹。
设备安装的apk、以及应用使用过程中产生一些文件如:SharedPreference键值对文件,数据库Sqlite文件均存储于该路径下。
内部存储位于系统中很特殊的一个位置,对于设备中每一个安装的 App,系统都会在 data/data/packagename/xxx自动创建与之对应的文件夹。
如果你想将文件存储于内部存储中,那么文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。对于这个内部目录,用户是无法访问的,除非获取root权限。

获取某个应用私有的内部存储路径:

String fileDir = context.getFilesDir().getAbsolutePath();
String cacheDir = context.getCacheDir().getAbsolutePath();

打印结果一般如下:

data/data/packagename/files
data/data/packagename/cache

部分手机的打印结果:

fileDir: /data/user/0/packagename/files
cacheDirDir: /data/user/0packagename/cache

可能与手机设置手机分身有关,当开启手机分身后打印结果为:

fileDir: /data/user/10packagename/files
cacheDirDir: /data/user/10/packagename/cache

context.getCacheDir()和context.getFilesDir()的区别

它们都位于内部存储,都是应用私有的目录。
getCacheDir对应内部存储的路径为: data/data/packagename/cache,但是对于部分手机取到的路径为:data/user/0/packagename/cache,它是应用程序的缓存目录,该目录内的文件在设备内存不足时会优先被删除掉,所以存放在这里的文件是没有任何保障的,可能会随时丢掉。
getFilesDir对应内部存储的路径为: data/data/packagename/files,位于该路径的文件会被长期存储,不会被清理。
当用户卸载应用时,这两个路径下的文件都会被删除。

外部存储

针对于外部存储比较容易混淆,因为在Android4.4以前,手机机身存储就叫内部存储,插入的SD卡就是外部存储,但是在Android4.4以后的话,就目前而言,手机机身出厂自带的存储也是归属于外部存储,若再插入SD卡的也称之为外部存储,因此对于外部存储分为两部分:SD卡和手机自带扩展内存.(值得一提的是Android手机逐渐摒弃外置SD卡)

外部存储应用私有目录路径获取

context.getExternalCacheDir()

获取外部存储应用私有的缓存。
对应外部存储路径:/storage/emulated/0/Android/data/packagename/cache
缓存目录中的文件可能会在系统需要空间时被清除。

context.getExternalFilesDir(String type)

	/**
     * @param type The type of files directory to return. May be {@code null}
     *            for the root of the files directory or one of the following
     *            constants for a subdirectory:
     *            {@link android.os.Environment#DIRECTORY_MUSIC},
     *            {@link android.os.Environment#DIRECTORY_PODCASTS},
     *            {@link android.os.Environment#DIRECTORY_RINGTONES},
     *            {@link android.os.Environment#DIRECTORY_ALARMS},
     *            {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
     *            {@link android.os.Environment#DIRECTORY_PICTURES}, or
     *            {@link android.os.Environment#DIRECTORY_MOVIES}.
     * @return the absolute path to application-specific directory. May return
     *         {@code null} if shared storage is not currently available.
     */
    @Nullable
    public abstract File getExternalFilesDir(@Nullable String type);

对应外部存储路径:/storage/emulated/0/Android/data/packagename/files

外部存储公有目录存储路径

在启用分区存储之前,SD卡里面的文件是可以被自由访问,即文件的数据对其他应用或者用户来说都是可以访问的,当应用被卸载之后,其卸载前创建的文件仍然保留。
对于SD卡上面的文件路径需要通过Environment获取,同时在获取前需要判断SD的状态:

// Checks if a volume containing external storage is available
// for read and write.
private boolean isExternalStorageWritable() {
    return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED;
}

// Checks if a volume containing external storage is available to at least read.
private boolean isExternalStorageReadable() {
     return Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED ||
            Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED_READ_ONLY;
}

通过Environment获取:

getExternalStorageDirectory()

对应外部存储路径:/storage/emulated/0

getExternalStoragePublicDirectory(String type)

获取外部存储的共享文件夹路径如:

DIRECTORY_MUSIC 音乐目录
DIRECTORY_PICTURES 图片目录
DIRECTORY_MOVIES 电影目录
DIRECTORY_DOWNLOADS 下载目录
DIRECTORY_DCIM 相机拍照或录像文件的存储目录
DIRECTORY_DOCUMENTS 文件文档目录

例:

String externalStoragePublicDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();

以上便是获取相机DCIM目录,对应获取的路径为:/storage/emulated/0/DCIM

参考

Android系统中内部存储和外部存储(公有目录、私有目录、缓存目录)详解
应用数据和文件
解析Android内部存储、外部存储的区别
一篇文章搞懂android存储目录结构

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值