Android内部存储与外部存储(私有目录与公共目录)图文详解

这篇具有很好参考价值的文章主要介绍了Android内部存储与外部存储(私有目录与公共目录)图文详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

   

目录

一、存储空间概述

二、存储空间的划分

1、存储划分

2、内部存储

2.1 内部存储概述

2.2 内部存储 - 私有目录

3. 外部存储

3.1 外部存储概述

3.2 外部存储 - 私有目录

3.3 外部存储 - 公共目录

三、内部存储与外部存储比较

1、横向对比

2、目录结构

3、存储分类

四、总结


    应用程序在 Android 系统运行过程中产生的用户数据、日志、下载的图片、文件等都需要存储在 Android 系统提供的存储空间里,所以有必要了解 Android 系统下存储空间的概念、分类、特点以及使用方法,在实际应用中采用适合的方式保存数据。

一、存储空间概述

    从存储介质来说,Android 的存储空间用于数据持久化存储,属于 ROM 存储介质,手机关机或者退出 App 数据不会丢失,这里需要和经常提到的“内存”从概念上进行区分:内存属于 RAM 存储介质,退出 App 或者关机之后数据会丢失。我们在开发Android应用的过程中,避免不了要用到数据持久化技术,所谓的数据持久化就是将 RAM 中的临时数据永久性保存到 ROM 中,保证在 App 退出或者手机关机后数据不会丢失。

    从存储结构来说,Android 系统的内核使用的是 Linux 内核, 所以 Android 的文件目录结构和 Linux 系统的文件目录结构类似。Android 系统使用虚拟文件系统(VFS), VFS 的目录是以"/"为根节点,根节点下又有不同的节点。例如:/data, /sytem, /mnt, /storage 等等。

二、存储空间的划分

    我们常用的数据持久化的方式有文件存储,数据库存储,SharedPreference存储等。在Android系统中有两个位置可以让应用实现数据持久化存储:内部存储外部存储

1、存储划分

    在 Android 4.4 之前设备的机身存储就是内部存储,而为了弥补内部存储空间不足而插入的外置 SD 卡,称为外部存储。

Android内部存储与外部存储(私有目录与公共目录)图文详解

    在包含 Android 4.4 之后的设备中,很多中高端机器都将自己的机身存储扩展到了 8G 以上,将同一块存储空间从概念上分成了内部存储(internal storage) 和外部存储(external storage) 两部分,但其实它们都在手机内部。当然,依然可以插入 SD 卡来扩充存储空间,这部分的存储空间称为扩展的外部存储空间。只是现在机身存储都比较大,很少插入 SD 卡了。

Android内部存储与外部存储(私有目录与公共目录)图文详解

     上面两张图合并到一张图的展示:

Android内部存储与外部存储(私有目录与公共目录)图文详解

2、内部存储

2.1 内部存储概述

    前面提到过,Android 系统以"/"为根节点,根节点下又有不同的节点,例如:/data, /sytem, /mnt, /storage 等。内部存储在逻辑上用目录来区分的话就是 /data 目录下的 data 文件夹:/data/data这个目录普通用户是无权访问的,用户需要手机 ROOT 权限才可以查看。不过开发者可以通过 Android Studio 的 View ---- Tool Windows ---- Device File Explorer 工具来查看该目录,内部存储目录的大致结构如下图所示。

Android内部存储与外部存储(私有目录与公共目录)图文详解

2.2 内部存储 - 私有目录

2.2.1 概述

    从上图可以看到,/data/data 目录是按照应用的包名来组织的,每个应用在安装成功后,会自动创建新的目录(data/data/package-name),并且目录名称就是该应用的包名,所以每个应用都有专属的内部存储目录。当应用被卸载后,该目录都会被系统自动删除。所以,如果你将数据存储于内部存储中,其实就是把数据存储到自己应用包名对应的内部存储目录中。

    每个应用的内部存储目录都是私有的,也就是说内部存储目录下的文件只能被宿主应用访问到,其他应用是没有权限访问的。宿主应用访问自己的内部存储目录时不需要申请任何权限。因此这部分的存储也被称为:内部存储私有目录

典型的内部存储私有目录结构如下,用户也可以根据需要自己创建新的目录:

Android内部存储与外部存储(私有目录与公共目录)图文详解

  • app_webview:用于存储webview加载过程中的数据,如Cookie,LocalStorage等。
  • cache:用于存储使用应用过程中产生的缓存数据。
  • code_cache:存放运行时代码优化等产生的缓存。
  • databases:主要用于存储数据库类型的数据。
  • files:可以在该目录下存储文件。
  • lib:存放App依赖的so库。
  • shared_prefs:用于存储SharedPreference文件。

2.2.2 特点

  • 与宿主 App 的生命周期相同,应用卸载时,会被系统自动删除。
  • 宿主 App 可以直接访问,无需权限;
  • 其他应用无权访问;
  • 用户访问需 Root 权限。
  • 适合存储与应用直接相关,隐私性或敏感性高的数据。

2.2.3 API相关

# 获取的目录是/data/data/package_name,即应用内部存储的根目录
context.getDataDir();

# 获取的目录是/data/data/package_name/files,即应用内部存储的files目录
context.getFilesDir();

# 获取的目录是/data/data/package_name/cache,即应用内部存储的cache目录
context.getCacheDir();

# 获取的目录是/data/data/package_name/name,如果该目录不存在,系统会自动创建该目录。
context.getDir(String name, int mode) 

# 不同的mode
MODE_APPEND:即向文件尾写入数据
MODE_PRIVATE:即仅打开文件可写入数据
MODE_WORLD_READABLE:所有程序均可读该文件数据,Api 17废弃
MODE_WORLD_WRITABLE:即所有程序均可写入数据,Api 17废弃

3. 外部存储

3.1 外部存储概述

    通俗来说,外部存储空间就是我们打开手机系统“文件管理”后看到的内容,外部存储的最外层目录是 storage 文件夹,也可以是 mnt 文件夹,这个厂家不同也会有不同的结果。一般来说,在 storage 文件夹中有一个 sdcard 文件夹,和内部存储不同的是,外部存储根据存储特点的不同可分为三种类型:私有目录公共目录、其他目录。其中,“私有目录”属于外部存储的“私有存储空间,“公共目录”和“其他目录”属于外部存储的“共享空间

    通常来说,应用涉及到的持久化数据分为两类:应用相关数据应用无关数据。前者是指专供宿主 App 使用的数据信息,比如一些应用的配置信息,数据库信息,缓存文件等。当应用被卸载,这些信息也应该被随之删除,避免存储空间产生不必要的占用,适合放到(内部存储或外部存储)“私有目录”。后者更偏向于这类信息:当应用被卸载,用户仍然希望保留于设备当中的信息。常见如,拍照类应用的图片文件,用户是使用浏览器手动下载的文件等。应用无关数据应该是宿主应用希望与其他应用共享的数据,适合存放在外部存储空间的“公共目录”或“其他目录”。

Android内部存储与外部存储(私有目录与公共目录)图文详解

  • 私有目录:上图中的 Android 文件夹,这个文件夹打开之后里边有一个 data 文件夹,打开这个 data 文件夹,里边有许多包名组成的文件夹,这些文件夹是应用的私有目录。
  • 公共目录:DCIM、Download、Music、Movies、Pictures、Ringtones 等这种系统为我们创建的文件夹;这些目录里的文件所有应用可以分享。
  • 其他目录:除私有目录和公共目录之外的部分。比如各个 App 在 /sdcard/ 目录下创建的目录,如支付宝创建的目录:alipy/,微博创建的目录:com.sina.weibo/,qq创建的目录:com.tencent.mobileqq/等。

3.2 外部存储 - 私有目录

3.2.1 特点

  • 与宿主 App 的生命周期相同,应用卸载时,会被系统自动删除。
  • 宿主 App 可以直接访问,无需权限。(备注:从 4.4 版本开始,宿主 App 可以直接读写外部存储空间中的应用私有目录, 4.4 版本之前,开发人员需在 Manifest 申请外部存储空间的文件读写权限。)
  • 其他 App 可以访问。(备注:自 Android 7.0 开始,系统对应用私有目录的访问权限进一步限制。其它App无法通过 file:// 这种形式的 Uri 直接读写该目录下的文件内容,需通过 FileProvider 访问。)
  • 用户可直接访问,无需权限。
  • 适合存储与应用直接相关,隐私性或敏感性都不高的数据。

3.2.2 API相关

同样,Android SDK 中也提供便捷的 API 供开发人员直接操作外部存储空间下的应用私有目录:

# 获取到的目录是 /storage/emulated/0/Android/data/package_name/cache
Context.getExternalCacheDir() 

# 如果type为"",那么获取到的目录是 /storage/emulated/0/Android/data/package_name/files,  如果type为"test",那么就会创建/storage/emulated/0/Android/data/package_name/files/test目录
Context.getExternalFilesDir(String type) 

3.3 外部存储 - 公共目录

3.3.1 特点

  • 与宿主 App 生命周期无关,应用卸载后,数据仍然保留;
  • 所有的App都需要申请 EXTERNAL_STORAGE 权限,Android 6.0 开始需申请动态权限;
  • 用户访问,无需权限。
  • 适合存储不敏感的数据,且希望与其他应用共享的数据。

3.3.2 API相关

# 获取到的目录是/storage/emulated/0,这个也是外部存储的根目录。
Environment.getExternalStorageDirectory() 

/* 
1.如果type为"",那么获取到的目录是外部存储的根目录即  /storage/emulated/0
2.如果type为"test",那么就在外部存储根目录下创建test目录,android官方推荐使用以下的type类型,我们在Sdcar的根目录下也经常可以看到下面的某些目录:
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_PODCASTS = "Podcasts";
public static String DIRECTORY_RINGTONES = "Ringtones";
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
*/
Environment.getExternalStoragePublicDirectory(String type) 

三、内部存储与外部存储比较

1、横向对比

Android内部存储与外部存储(私有目录与公共目录)图文详解

2、目录结构

Android内部存储与外部存储(私有目录与公共目录)图文详解

Android内部存储与外部存储(私有目录与公共目录)图文详解

3、存储分类

Android内部存储与外部存储(私有目录与公共目录)图文详解

四、总结

    总的来说,如果你的应用需要存储“私密性高且与应用相关”的数据,就应该选择内部存储的私有目录,“私密性不高但与应用相关”的数据就应该选择外部存储的私有目录,两者在卸载应用后,都会被系统自动删除,如果“私密性不高且与其他应用共享,应用卸载后还希望保留”,就应该选择外部存储的公共目录或其他目录。

疑问:看了不少文章都说,因为“内部存储”空间有限或比较小,所以“内部存储”应该只存储一些占用空间较小的文件,大文件尽量选择“外部存储”空间?

    笔者认为现在内部存储和外部存储都是同一块存储介质上,除非系统刻意限制,两者存储空间的上限应该只受存储介质总容量和剩余容量的限制。为了验证一下,笔者通过 Adroid Studio 连接手机后,在终端执行命令:adb shell df -h,来查看分区的大小。笔者手机总的 ROM 存储空间是256G,从下面看到 /data 空间分配了226G,并且与下面的 /storage/emulated, /mnt/mdfs/sdcard 的空间都是相同的 226G。所以应该不存在说内部存储空间被限制到很小的情况,应该是“内部存储”和“外部存储”共享相同大小的存储空间。

Android内部存储与外部存储(私有目录与公共目录)图文详解

     可以看到剩余存储空间大小是 117G,这个与我查看手机的存储信息是一致的:

Android内部存储与外部存储(私有目录与公共目录)图文详解

    为了进一步验证下,我特意使内部存储私有目录的 Cache 文件总用量超过 1G 的大小,并没有出现因为在内部存储的文件总容量过大而被系统自动清理的情况。如果你还是觉得不放心,也可以选择在“外部存储”存放数据。另外,因为“内部存储”对用户来说是不可见的(需 ROOT 权限),如果你希望比较方便地浏览或操作应用的某些数据,那么就应该选择将这类数据存储到“外部存储”的“私有目录”或“其他目录”。

    另外,Android 10 开始,在 Manifest 增加了新属性:android:hasFragileUserData="true",如果这里的值为“true”,在卸载 App 的时候,在弹出的对话框里可以由用户勾选是否保留数据。如果勾选的话,那么“外部存储 - 应用私有目录”中数据就会保留,而不会被系统清理,这也算得上是 Android 系统比较人性化的一面吧。但是不管这里是否勾选,内部存储私有目录里的数据都会被系统删除。文章来源地址https://www.toymoban.com/news/detail-502328.html

到了这里,关于Android内部存储与外部存储(私有目录与公共目录)图文详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Solidty基础篇2-映射、msg、require、继承、引入、存储变量、函数内部和外部可见性

    映射(Mapping)和地址(Address) 映射_ 是另一种在 Solidity 中存储有组织数据的方法。 映射本质上是存储和查找数据所用的键-值对。在第一个例子中,键是一个 address,值是一个 uint,在第二个例子中,键是一个uint,值是一个 string。 msg.sender 有一些全局变量可以被所有函数调

    2023年04月09日
    浏览(34)
  • Android 允许其他应用读取本应用的私有目录

    在Android中,应用默认是封闭的,不允许其他应用访问自己的私有目录。但是,如果你想要让其他应用能够访问你的应用中的某些文件,你可以使用FileProvider类来实现这一功能。 以下是使用FileProvider的步骤: 1. 在你的应用的 AndroidManifest.xml 文件中声明FileProvider: 2. 在 res/xm

    2024年04月12日
    浏览(37)
  • 【大数据Hive】Hive 内部表与外部表使用详解

    目录 一、hive 内部表简介 1.1 查看内部表信息 二、hive 外部表简介

    2024年02月16日
    浏览(33)
  • Android 10-11适配外部存储方案

    Android Api 29 对文件和文件夹进行了重大更改。不允许使用外部存储,如下方法: Environment.getExternalStorageDirectory() = /mnt/sdcard   Environment.getExternalStoragePublicDirectory(“test”) = /mnt/sdcard/test 只能使用内部存储 getExternalFilesDir(“test”) = /mnt/sdcard/Android/data/com.my.app/files/test getExternalF

    2024年02月06日
    浏览(38)
  • Android 获取内部存储中音乐文件的正确姿势

    最近想写一个音乐的小APP出来(doge),借此熟悉音频开发的相关技术。但是在获取 内部存储的音乐文件 时踩了一些坑...所以有了这篇帖子,简单介绍下Android的存储类别,以及如何获取内部存储中的音乐文件。 首先要理解一个概念, 内存≠内部存储 。 内存 - 程序运行是内

    2024年02月08日
    浏览(40)
  • Android 12.0 kenel中修改rom系统内部存储的大小

     在12.0的系统rom产品开发定制中,在对一些产品开发中的配置需求方面,由于在产品后续订单中,有些产品是出口的,但是硬件方面已经定板,时间比较仓促,所以 就需要软件方面在rom内部存储的大小方面作假,修改rom真实的大小容量,所以就需要在kenel驱动部分来修改这部

    2024年02月13日
    浏览(42)
  • Android13关于获取外部存储文件的相关问题及解决方案记录

      Android的学习路上... 测试设备:vivo X90s 安卓版本: Android13 开发环境:AndroidStudio Flamingo SDK:33 最近我在Android13的环境下尝试写一个 文件选择器 ,以便日后的开发使用。但是我们知道,从Android13 (API33) 开始,外部存储权限发生了变化,要想读取外部存储文件,使用原来的权

    2024年01月15日
    浏览(65)
  • Android 访问存储卡的三种主要的目录

    Android 访问存储卡(即外部存储)通常涉及以下三种主要的目录: 1. 外部存储公共目录 (Public External Storage) 这些目录对所有应用都是可见的,并且不需要任何特殊权限来读取媒体文件。但是从Android 10(API 级别 29)开始,如果要写入这些目录,则需要 WRITE_EXTERNAL_STORAGE 权限,

    2024年01月24日
    浏览(56)
  • GitHub中如何创建自己的存储库?(图文详解)

    目录 一、创建自己的存储库? 二、详细介绍 1、Repository name 2、Descriptioin(optional) 3、Public、Private 4、Initialize this repository with 5、Add a README file 6、Add .gitignore 7、Choose a license 三、完成创建存 四、新建文件搭建 1、创建新文件 2、上传文件 五、如何删除储存库 六、GitHub如何恢

    2024年02月02日
    浏览(53)
  • 【图文详解】Unity存储游戏数据的几种方法

    在Unity中,常用的数据存储方法包括PlayerPrefs、ScriptableObject、JSON、XML和数据库等。 PlayerPrefs是Unity自带的一种简单的键值存储系统,适合存储一些简单的游戏数据。ScriptableObject是一种Unity类,可用于创建可序列化的对象并存储数据。JSON和XML是轻量级的数据交换格式,可以通过

    2023年04月08日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包