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

news2025/1/12 2:59:53

   

目录

一、存储空间概述

二、存储空间的划分

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

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

2、内部存储

2.1 内部存储概述

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

2.2 内部存储 - 私有目录

2.2.1 概述

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

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

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

  • 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 文件夹,这个文件夹打开之后里边有一个 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、横向对比

2、目录结构

3、存储分类

四、总结

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

    看了不少文章都说,因为内部存储空间有限,所以尽量选择外部存储空间,但是笔者认为现在内部存储和外部存储都是同一块存储介质上,除非系统刻意限制,两者存储空间的上限应该只受存储介质总容量和剩余容量的限制。

    为了验证一下,我在内部存储私有目录的 Cache 文件夹下缓存了超过 1G 的文件,暂时还没有出现因为缓存过多被系统自动清理的情况,但这点我也不是很明确,可以后续再做补充。如果实在不放心存储文件过大过多超过上限,就选择在外部存储存储数据。另外,因为内部存储对用户来说是不可见的(需 ROOT 权限),如果你希望能够浏览或操作应用的数据,那么就应该选择外部存储的“私有目录”或“其他目录”存储数据。

    另外,Android 10 开始,在 Manifest 增加了新属性:android:hasFragileUserData="true",如果这里的值为“true”,在卸载APP的时候,在弹出的对话框里可以由用户勾选是否保留数据。如果勾选的话,那么“外部存储 - 应用私有目录”中数据就会保留,而不会被系统清理,这也是 Android 系统比较人性化的一面。但是不管这里是否勾选,内部存储私有目录里的数据都会被系统删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/548411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

English Learning - L3 作业打卡 Lesson3 Day15 2023.5.19 周五

English Learning - L3 作业打卡 Lesson3 Day15 2023.5.19 周五 引言🍉句1: We present more expressions about food.成分划分连读爆破语调 🍉句2: They are from Elenir Scardueli, a listener in Brazil.成分划分弱读连读语调 🍉句3: My m…

plsql为什么连不上远程或本地的Oracle,需要做哪些准备?

文件配置解说 tnsnames.ora文件 文件所在地址:ORACLE_HOME\network\admin ORACLE_HOME:Oracle数据库或者客户端软件所在的地址 但是我的在Oracle数据库的目录下,而不是Oracle客户端软件(instantclient_11_2)下 里…

分布式架构设计及理论指导

目录 核心概念分布式分布式SOA架构微服务架构微服务技术对比 服务拆分拆分思想和原则创建父类工程创建子工程 远程调用方式引入RestTemplate CAP/BASE理论CAP理论分区容错 (Partition-tolerance)一致性(Consistency)可用性&#x…

【C++】继承/虚拟继承/菱形虚拟继承

继承 继承的概念继承体系中对象赋值转换继承方式对继承后的访问限定(重定义-同名隐藏)继承体系中派生类的默认成员函数友元函数、静态成员在继承中的特点菱形继承和菱形虚拟继承 继承的概念 为了让代码可以复用,当前类可以继承其他类的成员变…

阿里云OSS存储空间绑定自定义域名,浏览器通过自定义域名预览文件

阿里云官方文档: 如何绑定自定义域名_对象存储-阿里云帮助中心 华东1(杭州)地域创建了名为monkey的存储空间 Bucket:monkey Endpoint:oss-cn-hangzhou.aliyuncs.com 上传文件默认域名的url: https://monkey.oss-cn-han…

微信小程序nodejs+vue课程推荐报名学习分享平台uniapp

本文以实际运用为开发背景,运用软件工程原理和开发方法, 整个开发过程首先对课程分享平台进行需求分析,得出课程分享平台主要功能。接着对课程分享平台 进行总体设计和详细设计。总体设计主要包括小程序功能设计、小程序总体结构设计、小程序…

Python数据可视化小结

1. 引言 原始形式的数据对大多数人来说可能都是枯燥乏味的,但是如果掌握正确的可视化工具,给人的印象就会变得引人入胜。本文通过实际例子,让我们利用数据可视化工具来探索不一样的数据体验。 闲话少说,我们直接开始吧&#xff…

推荐3款超好用的海报设计软件!

在现代社会,海报设计已经成为了一种非常重要的视觉传达方式。如果你需要制作一个引人注目的海报,但却没有设计师的技能和经验,那么在线海报设计图片软件就是你的最佳选择。下面我们将介绍 5 款最受欢迎的在线海报设计图片软件,它们…

qt中使用QGIS实现二次开发导入shp格式地图(MSVC2019_64bit+qt5.15+qgis)

在qt开发过程中可能要导入自定义格式的图层地图,那么可以把这些数据导入qgis然后导出为shp格式文件,然后下载qgis源码,在qt项目中配置环境变量导入qgis有关的头文件,然后再引入shp数据格式的地图。 qgis处理数据 QGIS安装 QGIS…

oracle数据库当中用户的创建,添加,授权,以及表的创建与表的简单介绍,以及在oracle数据库当中的约束以及约束条件的简单介绍

系列文章目录 (3条消息) oracle数据库简介 文章目录 系列文章目录 前言 一、用户的创建 1.1、创建命令 1.2、给予scott用户权限 1.3、以scott用户进行连接登录 二、表和表的设计原则 2.1、表的概念 2.1.1、表是从属于用户的 2.1.2、表是逻辑表(概念表),不…

[比赛简介]Predict Student Performance from Game Play

比赛链接:https://www.kaggle.com/competitions/predict-student-performance-from-game-play/overview 比赛简介 本次比赛的目标是实时预测学生在基于游戏的学习中的表现。您将开发一个在最大的游戏日志开放数据集之一上训练的模型。 您的工作将有助于推进对基于…

Next.js ---未完待续....

Next.js 1.介绍2.体会服务器端渲染2.1为什么这就服务器端渲染了? 3.如何判断是否是服务器端渲染?--- 响应头信息4.文件名路由5.如何启动项目*另外1.Next.js 是基于 Webpack 的框架?1.1所以无需手动编译 TypeScript 代码 1.介绍 Next.js 是一…

【C++】C++泛型编程 | 模板初阶

🧑‍🎓个人主页:简 料 🏆所属专栏:C 🏆个人社区:越努力越幸运社区 🏆简 介:简料简料,简单有料~在校大学生一枚,专注C/C/GO的干货分…

LT8711UXE1,Type-C/DP1.2 转 HDMI2.0,内置HDCP,支持4k 60Hz向下兼容

1. 描述 LT8711UXE1 是一款高性能 Type-C/DP1.2 至 HDMI2.0 转换器,设计用于将 USB Type-C 源或 DP1.2 源连接到 HDMI2.0 接收器。LT8711UXE1 集成了一个符合 DP1.2 标准的接收器和一个符合 HDMI2.0 标准的发射器。此外,还包括两个用于 CC 通信的 CC 控…

研发/IT工程师双视角测评8大仿真平台,结果……

上一篇,我们围绕着亿万研发工程师的梦想,考察了市面上几乎所有类型的工业仿真平台,深度评测了他们本质究竟是什么,适用场景有哪些,分别能给研发和IT工程师们减轻多少工作量。 据此,我们搭建了一个工业仿真…

C++/PTA 神坛

C/PTA 神坛 题目要求解题前提及思路凹包算法概念步骤 解题思路 代码tan(y/x)及tan2(y,x)函数 总结 题目要求 在古老的迈瑞城,巍然屹立着 n 块神石。长老们商议,选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比,因此神坛的面…

记录:自回归 模型在记忆 全随机序列 的潜变量 统计量爆炸现象

只是一个记录 8层12头512维度的 GPT 模型,使用它来记忆 10000 条 512长度 的无序序列,vocab_size 为100。 模型要自回归生成这些序列,不可能依赖局部推理,必须依赖全局视野,即记住前面的序列。 然后统计 最后一个no…

HF宣布在transformers库中引入首个RNN模型:RWKV,一个结合了RNN与Transformer双重优点的模型

RWKV是一个结合了RNN与Transformer双重优点的模型架构。由香港大学物理系毕业的彭博首次提出。简单来说,RWKV是一个RNN架构的模型,但是可以像transformer一样高效训练。今天,HuggingFace官方宣布在transformers库中首次引入RNN这样的模型&…

QGC局域网内连接PX4模拟器JMAVSim

环境 QGroundControl 开源地面站系统; 代码地址: https://github.com/mavlink/qgroundcontrolPX4 开源飞控系统; 代码地址: https://github.com/PX4/PX4-Autopilot QGC可以直接下载运行包. PX4 请根据代码中的说明,进行环境的配置和运行. 通过代码去build地面站和PX4的步骤见官…