先来看一下我们本章节的思维导图,希望能够帮助你用碎片化或者尽量短的时间,直白、深刻的了解本文的知识点。

内部存储

是否需要用户权限:否

是否能被其他应用访问:否

卸载应用数据是否被删除:是

内部存储控件不需要用户权限,这意味着我们不需要用户去授权 android.permission.WRITE_EXTERNAL_STORAGE 和 android.permission.READ_EXTERNAL_STORAGE 我们就可以读写该目录下的文件。而且该目录下的文件不能被其他应用访问。这也就保证了我们应用内部存储的文件的安全性和隐私性,如果我们需要查看自己应用内部的文件,我们可以通过Android Studio的 Device File Explore 工具进行访问:

我们可以访问/data/data/应用包名,查看自己应用下的内部存储文件。

/data/data/应用名/cache:存放的是APP的缓存信息

/data/data/应用名/code_cache:在运行时存放应用产生的编译或者优化的代码

/data/data/应用名/files: 存放APP的文件信息

还有一些运行时,产生的文件夹,例如调用SharedPreference所产生的 /data/data/应用包名/shared_prefs 目录,存放着app的SharedPreference所产生的 xml 文件,还有调用 数据库 所产生的 **/data/data/应用包名/databases/**文件夹,这里就不一一举例。

相关API

getCacheDir

File getCacheDir() 返回内部存储的cache文件夹

Log.d("DaMai",getCacheDir().getPath()); //data/user/0/com.example.vicky.yinji/cache

复制代码

getCodeCacheDir

File getCodeCacheDir() 返回内部存储的code_cache文件夹,要求Android5.0+

Log.d("DaMai",getCodeCacheDir().getPath()); ///data/user/0/com.example.vicky.yinji/code_cache

复制代码

getFilesDir

File getFilesDir() 访问内部存储的files目录

Log.d("DaMai",getFilesDir().getPath()); ///data/user/0/com.example.vicky.yinji/files

复制代码

fileList

String[] fileList() 返回files目录下的文件名,例如files目录下有test.txt文件和test1.txt文件

//输出 test.txt和test1.txt

for (String item : fileList()){

Log.d("DaMai",item);

}

复制代码

openFileOutput

FileOutputStream openFileOutput() 写文件到files目录下:

try {

FileOutputStream outputStream = openFileOutput("test.txt", Context.MODE_PRIVATE);

outputStream.write("this is test content".getBytes());

outputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

复制代码

此时file目录下就会多了一个test.txt文件

openFileInput

FileInputStream openFileInput() 读files目录下文件,例如我们读刚刚写入的test.txt文件

// 输出:this is test content

try {

FileInputStream fileInputStream = openFileInput("test.txt");

byte[] bytes = new byte[1024];

StringBuffer stringBuffer = new StringBuffer();

int len = 0;

while ((len=fileInputStream.read(bytes))!=-1){

stringBuffer.append(new String(bytes,0,len));

}

Log.d("DaMai",stringBuffer.toString());

fileInputStream.close();

} catch (Exception e) {

e.printStackTrace();

}

复制代码

getDataDir

File getDataDir() 返回内部存储的根文件夹,要求Android7.0+

Log.d("DaMai",getDataDir().getPath()); ///data/user/0/com.example.vicky.yinji

复制代码

外部存储

公共目录

是否需要用户权限:是

是否能被其他应用访问:是

卸载应用数据是否被删除:否

公共目录必须需要用户授权读写的权限,这意味着我们需要在 AndroidManifest.xml 中注册用户权限。

复制代码

并且在Android 6.0系统之后需要申请用户权限,并获得用户授权,才能读写文件。

公共目录相对开放,我们可以访问其他APP存在公共目录下的文件,并且当APP被删除时,并不会删除应用存在公共目录下的文件。

我们可以通过Environment对象,访问读写公共目录的文件。接下来让我们看看相关的API。

相关API

Environment.getExternalStorageDirectory

File Environment.getExternalStorageDirectory() 访问外部存储设备公共根目录:

//输出:/storage/emulated/0

Log.d("DaMai",Environment.getExternalStorageDirectory().getPath());

复制代码

Environment.getExternalStoragePublicDirectory

File Environment.getExternalStoragePublicDirectory(String type)

我们可以通过type访问公有目录下对应的文件,例如:

//输出:/storage/emulated/0/Music

Log.d("DaMai",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath());

复制代码

Environment对象为我们提供了丰富的访问对应公有目录下的type,我们可以通过Environment对象源码进行查看,这里不再赘述。

Environment.getExternalStorageState

String Environment.getExternalStorageState() 获得外部存储SD卡的状态,在读写SD卡的时候,我们应该先判断一下SD卡的状态,是否能够支持读写。

具体返回值及对应的状态也可以查看Environment.getExternalStorageState的源码。

私有目录

是否需要用户权限:4.4以上不需要

是否能被其他应用访问:否

卸载应用数据是否被删除:是

私有目录,在Android4.4系统以上。不需要注册和用户授权SD读写的权限,就可以在应用的私有目录进行读写文件。并且文件不能被其他应用所访问,具有较好的隐私性和安全性,并且在用户删除的时候,对应的应用私有目录也会被删除。

私有目录地址:/storage/emulated/0/Android/data/应用包名

相关API

私有目录下访问的API都在ContextWrapper对象上。这意味这我们可以直接在Activity中调用或者通过Context对象去调用。

getExternalCacheDir

File Context.getExternalCacheDir() 访问/storage/emulated/0/Android/data/应用包名/cache目录,该目录用来存放应用的缓存文件,当我们通过应用删除缓存文件的时候,该目录下的文件会被清除。

//输出:/storage/emulated/0/Android/data/com.example.vicky.yinji/cache

Log.d("DaMai",this.getExternalCacheDir().getPath());

复制代码

getExternalFilesDir

File Context.getExternalFilesDir(String type) 访问/storage/emulated/0/Android/data/应用包名/files 目录,该目录用来存放应用的数据,当我们通过应用去清除应用数据的时候,该目录下的文件会被清除。我们也可以通过type,去创建并获得对应目录下的File文件。例如:

//创建并输出:/storage/emulated/0/Android/data/com.example.vicky.yinji/files/test

Log.d("DaMai",this.getExternalFilesDir("test").getPath());

复制代码

我们也可以将type传为null,这时候访问的目录就是files目录,例如:

//输出:/storage/emulated/0/Android/data/com.example.vicky.yinji/files

Log.d("DaMai",this.getExternalFilesDir(null).getPath());

复制代码

复盘

我们开发中经常会进行文件存储,这次我们终于弄清楚了Android的文件存储,当我们需要存储一些私密性和安全性比较高的小数据,例如用户的账号密码等信息,我们可以存放在内部存储空间上;当我们需要存放一些能够被其他应用也能访问的数据,并且当应用被删除的时候,不希望数据被清除的时候,我们可以放到外部存储的公有目录下,但别忘了申请读写SD卡的权限哦;当我们需要存放一些应用的数据和缓存数据,希望有较好的隐私性和应用被删除的时候,对应的应用数据和缓存也被删除,这时候我们可以选择存放在外部存储的私有目录下。

我是大麦,如果喜欢我的文章,请给我一颗小心心。

android文件存储的有点,快速理解Android文件存储路径相关推荐

  1. Flutter 对 iOS、Android(双端开发者)的快速理解(一)

    原文链接 更多教程 如果你有移动端开发经验,无论你是iOS还是Android开发者,你都可以利用现有的知识快速理解Flutter开发. 本文会通过对比双端开发和Flutter中的差异来说明. Flut ...

  2. Android 系统(57)---深入理解Android输入系统

    <深入理解Android 卷III>第五章 深入理解Android输入系统 <深入理解Android 卷III>即将发布,作者是张大伟.此书填补了深入理解Android Fra ...

  3. Android 手写Binder 教你理解android中的进程间通信

    关于Binder,我就不解释的太多了,网上一搜资料一堆,但是估计还是很多人理解的有困难.今天就教你如何从 app层面来理解好Binder. 其实就从我们普通app开发者的角度来看,仅仅对于androi ...

  4. android toolbar源码解析,深入理解Android 5.0中的Toolbar

    环境说明: Android Studio 2.0 V7包版本:com.android.support:appcompat-v7:23.4.0 compileSdkVersion 23 buildToo ...

  5. java文件序列化_通过快速Java和文件序列化加快速度

    java文件序列化 从Java的第一个版本开始,许多开发人员每天都在努力实现至少与C / C ++一样好的性能. JVM供应商正在通过实现一些新的JIT算法来尽力而为,但仍有许多工作要做,尤其是在我们 ...

  6. 怎么快速搜索服务器里的文件,使用 Everything,快速搜索电脑文件,制作局域网资料搜索器 | 科技搜...

    所需工具:Everything 在 Windows 系统中,已经有自带的资源管理器文件查找功用,当然也有其他的一些软件辅佐查找,但是这些都不及一款软件,名字叫 Everything ,速度非常快,支持 ...

  7. tsd3dmapper软件使用方法_TS文件连接器:如何快速合并TS文件?

    吴川 华南区技术负责人 概要 TS是"Transport Stream"的缩写,它是一种音视频封装格式,格式全称为MPEG2-TS.当我们想合并多个TS文件,或者想将TS文件与其他 ...

  8. .rpt文件内容读取java_Java快速入门(26) 文件和IO操作

    点击上方蓝色"小白轻松学编程",添加"关注" (*平遥古城,图片来源于网络) 文章目录 1 前言2 流3 字节流4 字符流5 标准流6 读取文件7 File和I ...

  9. android studio一个页面等待3秒跳转_Flutter 对 iOS、Android(双端开发者)的快速理解(二)

    原文链接 更多教程 Flutter怎么在不同页面之间跳转? 在 iOS 中,你可以使用管理了 view controller 栈的 UINavigationController 来在不同的 view ...

  10. 快速理解android View的测量onMeasure()与MeasureSpec

    笔者之前有一篇文章已经使用onMeasure()解决了listview与scollview的显示冲突问题,博客地址如下: onMeasure简单方法 完美解决ListView与ScollView冲突问 ...

最新文章

  1. Codeforces Round #665 (Div. 2) Maximum Distributed Tree(树上贪心)
  2. UIScrollView 使用
  3. 多线路虚拟主机解决方案
  4. scala与python混合调用实验
  5. Spark常规性能调优三:并行度调节
  6. 用HTTP的PUT方式发送请求
  7. access日期如何增加年数_如何为Access数据库表添加日期或时间戳
  8. 数据冗余的理解和相关概念
  9. oracle近三个月内,在oracle中的前三个月SQL
  10. apache 支持 php5
  11. linux sftp ssh端口分开,sftp ssh服务分离
  12. LeetCode 第 69 场力扣双周赛
  13. Mybatis核心配置文件SqlMapConfig.xml
  14. mysql slave_mysql master slave
  15. c语言进阶.pdf,C语言程序设计进阶:文件.pdf
  16. ceil函数_pyspark常用函数
  17. C++11多线程std::thread的简单使用
  18. 基于物联网的温度采集系统(一):底层感知网络搭建
  19. 计算机鼠标左键的主要应用,鼠标的应用
  20. 监督学习算法的发展史和它们之间的关系:从文氏图到回归、决策树、支持向量机和人工神经网络...

热门文章

  1. 微软Windows系统命令和Sysinternals系列工具
  2. js 验证文本框为数字的正则表达式
  3. 启动vue项目的时候报错提示To install it, you can run: npm install --save core-js/modules/es.regexp.dot
  4. 线程的简单理解,适用于初接触的小白,另类例子讲解,通俗易懂
  5. mui的实例项目源码_Spring Boot 2.x 启动全过程源码分析
  6. 【转】Topshelf 搭建 Windows 服务
  7. mysql使用总结(C#)
  8. 【转】详解vue的diff算法
  9. prototype.js学习(3)函数绑定
  10. 适用与IOS手机的python编辑器,让你不限空间,地点都能玩转pyhton代码 !...