一、背景

作为一个开发者,我们经常需要通过缓存一些文件到SD卡中,常见的方式就是,通过:

File sdCard = Environment.getExternalStorageDirectory();

获取SD卡根目录,然后自定义文件/文件名进行文件存储.这样做法的结果就是,当手机安装了大量的app时,SD卡根目录会迅速变得杂乱不堪。并且在API 6.0之后,根目录文件存储是需要用户授权的,就算你在AndroidManifest.xml中配置了存储权限,用户不授权也是写不进去了

SD卡读写权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

其实,Google已经提供了最佳的外部存储方案,那就是统一路径为:

/Android/data/< package name >/files/… (该路径通常挂载在/mnt/sdcard/下)

外部存储路径调用方法是: context.getExternalFilesDir(dir).getAbsolutePath()   //通过context调用,

参数dir为自自定义文件夹.这个方法获得的文件存储路径适用于6.0以后系统,主要AndroidManifest.xml配置读写权限了,就不需要用户再授权了.

内部存储路径调用方法是:context().getCacheDir().getAbsolutePath() //通过context调用

二、本地存储路径常用方法介绍

1. getCacheDir()

  • 路径/data/data/<package_name>/cache/

  • 存储类型:内部存储(应用私有目录)。

  • 特点

    • 无需权限,应用卸载时自动删除。

    • 适合存放临时缓存文件(如图片缓存)。

    • 系统可能在存储不足时清理此目录(但依赖系统实现,不保证及时性)。

  • 示例

    File cacheDir = context.getCacheDir();


2. getFilesDir()

  • 路径/data/data/<package_name>/files/

  • 存储类型:内部存储(应用私有目录)。

  • 特点

    • 无需权限,应用卸载时自动删除。

    • 适合存放长期使用的私有文件(如用户配置、数据库文件)。

    • 系统不会自动清理,需开发者管理。

  • 示例

    File filesDir = context.getFilesDir();


3. getExternalFilesDir(String type)

  • 路径/Android/data/<package_name>/files/<type>/
    (例如 Environment.DIRECTORY_DOWNLOADS 指定子目录)

  • 存储类型:外部存储(应用私有目录)。

  • 特点

    • 从 Android 4.4(API 19)开始无需权限;但若访问其他应用的目录或公共目录(如 DCIM)仍需权限。

    • 应用卸载时自动删除。

    • 适合存放媒体文件等较大数据(如音视频、文档)。

    • 用户可通过文件管理器直接访问(需注意隐私问题)。

  • 示例

  • File externalFilesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);


4. getExternalCacheDir()

  • 路径/Android/data/<package_name>/cache/

  • 存储类型:外部存储(应用私有目录)。

  • 特点

    • 与 getExternalFilesDir() 类似,但专用于缓存文件。

    • 系统或用户可能手动清理此目录。

    • 适合存放临时外部缓存(如下载的临时文件)。

  • 示例

    File externalCacheDir = context.getExternalCacheDir();

5. Environment.getExternalStorageDirectory()

  • 已废弃 (API 29+),建议使用 Context#getExternalFilesDir(String) 或其他存储访问框架

  • 返回共享的外部存储根目录 (如 /storage/emulated/0)

  • 需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 权限

  • 存储在此处的文件对所有应用可见,用户也可以通过文件管理器访问

  • 应用卸载时文件不会被自动删除

三、路径说明和对比

getCacheDir():/data/data/你的应用的包名/cache
getFilesDir():/data/data/你的应用的包名/files
getExternalFilesDir():SDCard/Android/data/你的应用的包名/files/
getExternalCacheDir():SDCard/Android/data/你的应用包名/cache/


从上文每个方法获取的路径中可以看出,getCacheDir()和getFilesDir()是获取手机自带的存储空间中的当前包文件的路径 ;
getExternalFilesDir()和getExternalCacheDir()是获取手机中SD卡的存储控件中的当前包文件的路径。

关键区别总结

区别方法存储位置是否需要权限卸载是否删除系统清理行为适用场景
external storage
外部存储
Environment.getExternalStorageDirectory()SD卡根目录:/storage/emulated/0已废弃,不建议再使用,推荐使用getExternalFilesDir代替
context.getExternalFilesDir(dir)路径:/storage/emulated/0/Android/data/<package_name>/files/...否(API 19+)较大的媒体或文档文件
context.getExternalCacheDir()路径:/storage/emulated/0/Android/data/<package_name>/cache/...否(API 19+)可能(用户/系统)外部临时缓存文件
internal storage
内部存储
context.getFilesDir()路径:/data/data/<package_name>/files适合存储应用长期使用的私有文件
context.getCacheDir()路径:/data/data/<package_name>/cache可能(低存储时)内部临时缓存文件

 注:/data/data/等同于/data/user/0

四、注意事项

1、权限问题

访问外部存储的公共目录(如相册)需 READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE 权限(Android 10+ 分区存储限制)。

私有目录(getExternalFilesDir/getExternalCacheDir)在 API 19+ 无需权限。

2、兼容性:

使用前检查外部存储是否可用:
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

3、存储选择建议:

小文件或敏感数据优先用内部存储(getFilesDir)。

大文件或用户需访问的文件用外部私有目录(getExternalFilesDir)。

4、清理责任:

缓存目录(getCacheDir/getExternalCacheDir)应定期清理,避免占用过多空间。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发的几种格式,TCP的十个重要机制

自定义协议中&#xff0c; 我们有几种常见的数据格式&#xff1a; 1.xml 通过标签来组织数据 请求&#xff1a; 优势&#xff1a; 让数据的可读性变更好了 劣势&#xff1a; 标签非常繁琐&#xff0c;传输的时候也占用更多网络带宽&#xff08;maven会使用xml来管理项目配…

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…

任务调度器-关于中心化调度 vs 去中心化调度的核心区别

1. 定义与架构模型 维度中心化调度去中心化调度核心角色存在一个中央调度器&#xff08;如XXL-JOB的调度中心&#xff09;&#xff0c;统一管理任务分配、状态监控和故障处理。无中心节点&#xff0c;调度逻辑分散在多个节点&#xff0c;通过共识算法&#xff08;如选举机制&a…

[论文阅读] 人工智能+软件工程 | 结对编程中的知识转移新图景

当AI成为编程搭档&#xff1a;结对编程中的知识转移新图景 论文信息 论文标题&#xff1a;From Developer Pairs to AI Copilots: A Comparative Study on Knowledge Transfer&#xff08;从开发者结对到AI副驾驶&#xff1a;知识转移的对比研究&#xff09; 作者及机构&#…

CAD多面体密堆积3D插件

插件介绍 CAD多面体密堆积3D插件可在AutoCAD内建立三维随机多面体密堆积模型。 插件内置物理动力学模拟算法&#xff0c;通过模拟重力、碰撞等现象&#xff0c;使多面体在虚拟环境中发生自然堆积&#xff0c;进而实现真实的堆积效果。多面体堆积模拟中存在的局部穿模问题可通…

VSCode CUDA C++进行Linux远程开发

环境准备 确保在本地和远程Linux服务器上安装了以下软件&#xff1a; Visual Studio Code&#xff08;简称VS Code&#xff09;Remote Development extension pack for VS CodeCUDA Toolkit&#xff0c;推荐版本为11.0或更高GCC编译器&#xff0c;用于C代码的编译 此外&…

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…

快速使用 Flutter Card 组件指南

目录 一、引言 二、Card 的基本用法 三、主要属性 3.1 elevation (阴影高度) 3.2 shape (形状) 3.3 color (颜色) 3.4 margin (外边距) 3.5 完整示例 四、结合 ListTile 组件使用 五、带图片的 Card 示例 六、注意事项 相关推荐 一、引言 Card 是 Flutter 提供的一个…

C语言内存管理和编译优化实战

参考&#xff1a; C语言内存管理“玄学”&#xff1a;从崩溃到精通的避坑指南C语言编译优化实战&#xff1a;从入门到进阶的高效代码优化技巧

【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录

【产品业务设计】支付业务设计规范细节记录&#xff0c;含订单记录、支付业务记录、支付流水记录 前言 我为什么要写这个篇文章 总结设计经验生成设计模板方便后期快速搭建 一个几张表 一共5张表&#xff1b; 分别是&#xff1a; 订单主表&#xff1a;jjy_orderMain订单产…

CppCon 2015 学习:Live Lock-Free or Deadlock

这段内容是介绍一场关于**“实用无锁编程&#xff08;Practical Lock-Free Programming&#xff09;”**的讲座提纲&#xff0c;重点在C中的并发编程。下面是详细的中文理解和分析&#xff1a; 讲座大纲和内容理解 主题概览 适当的“guru崇拜”和“祈求” → 开场调侃&#…

centos7编译安装LNMP架构

一、LNMP概念 LNMP架构是一种常见的网站服务器架构&#xff0c;由Linux操作系统、Nginx Web服务器、MySQL数据库和PHP后端脚本语言组成。 1 用户请求&#xff1a;用户通过浏览器输入网址&#xff0c;请求发送到Nginx Web服务器。 2 Nginx处理&#xff1a;Nginx接收请求后&…

Spark 写文件

Repartition Spark 输出文件数量 假设每个 Task 的输出数据都包含了全部 8 个分区值,那么最终的文件生成情况如下: 总文件数 = Task 数量 分区组合数 假设: ​Task 数量​:200 ​分区组合数​:8 个 (from_cluster 和 ds 的组合) 则: ​总文件数​:200 8 = ​1600 …

自定义protoc-gen-go生成Go结构体,统一字段命名与JSON标签风格

背景 在日常的 Go 微服务开发中&#xff0c;Protocol Buffers&#xff08;protobuf&#xff09; 是广泛使用的数据交换格式。其配套工具 protoc-gen-go 会根据 .proto 文件生成 Go 结构体代码&#xff0c;但默认生成的字段名、JSON tag 命名风格往往不能满足所有团队或项目的代…

LabVIEW的MathScript Node 绘图功能

该VI 借助 LabVIEW 的 MathScript Node&#xff0c;结合事件监听机制&#xff0c;实现基于 MathScript 的绘图功能&#xff0c;并支持通过交互控件自定义绘图属性。利用 MathScript 编写脚本完成图形初始化&#xff0c;再通过LabVIEW 事件结构响应用户操作&#xff0c;动态修改…

GD图像处理与SESSiON

SESSION: 原理: session与浏览器无关&#xff0c;但是与cookie有关 1.PHP碰到session_start()时开启session会话,会自动检测sessionID a. 如果cookie中存在&#xff0c;使用现成的 b. 如果cookie中不存在,创建一个sessionID&#xff0c;并通过响应头以cookie形式保存到浏览…

【Web应用】若依框架:基础篇14 源码阅读-后端代码分析-课程管理模块前后端代码分析

文章目录 一、课程管理模块前端代码截图二、前端代码及分析index.vuecourse.js 三、前端执行流程1. 组件初始化2. 查询操作3. 列表操作4. 对话框操作5. API 请求6. 执行流程总结关键点 四、课程管理模块后端代码截图五、后端代码块CourseControllerICourseServiceCourseMapperC…

深入理解系统:UML类图

UML类图 类图&#xff08;class diagram&#xff09; 描述系统中的对象类型&#xff0c;以及存在于它们之间的各种静态关系。 正向工程&#xff08;forward engineering&#xff09;在编写代码之前画UML图。 逆向工程&#xff08;reverse engineering&#xff09;从已有代码建…

DeepSeek12-Open WebUI 知识库配置详细步骤

&#x1f4da; Open WebUI 知识库配置详细步骤&#xff08;中英文对照&#xff09; &#x1f310; 界面语言切换 # 首次登录后切换语言&#xff1a; 1. 点击左下角用户头像 → Settings 2. 在 "General" 选项卡找到 "Language" 3. 选择 中文(简体)/Engli…