【Android文件存储1】Android 存储结构与路径访问

本文介绍了Android的文件存储结构,包括内部存储和外部存储的访问方法,如getFilesDir()、getCacheDir()、getExternalFilesDir()等,并详细讲解了如何构造文件路径和处理IOException,强调了应用私有空间的访问特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果有错误欢迎指正。

1、简介

Android 提供了文件系统,统一管理手机内的各种文件。
站在应用的角度,文件主要分为三类:

  1. 系统文件,包括底层的 Linux 驱动文件等,用户不可见。[root 除外]
  2. 内部存储,是私有的存储空间,开发者可以通过 Android SDK 提供的 API 访问,用户不可见。[root 除外] 其他应用不能访问。
  3. 外部存储,用户可见。开发者可以通过 Android SDK 提供的 API 访问。其他应用不能访问。

站在用户角度,分为系统文件,应用私有文件,以及普通的文件。其中系统文件用户不可见,应用私有文件中,外部存储中的文件用户可见。
也就是说:

  • 不可见的部分(内部存储),可以粗略分为两块:系统文件,以及应用的用户不可见私有文件;
  • 可见的部分(外部存储),分为用户可见的应用私有文件以及一般的文件。

一个应用拥有的在两个地方(内部存储、外部存储)存储的文件,其他应用不可以访问(除非应用主动通过内容提供器暴露路径),因而被称为应用私有空间

重点介绍的是应用层面的内部存储和外部存储两个部分。

2、内部存储

英文名称为 internal storage
可以通过 context 获取 API 访问,API 和功能如下:

getFilesDir()

获取 /data/data/<包名>/files 目录,返回 File 对象。

getDir()

获取 /data/data/<包名> 目录,返回 File 对象。

getCacheDir()

获取 /data/data/<包名>/cache 目录,返回 File 对象。

以上目录是专门为当前应用准备的,这部分对于用户来说不可见,不必申请权限
当 app 删除时,应用内部存储对应的目录以及其下的文件都会被删除。
如果应用不需要与其他应用共享文件的话,以上几个 API 足够应付应用文件存储了。

3、外部存储

英文名称为 external storage
可以通过 context 获取 API 访问。
外部存储实际上指的一般是 sd 卡。现在安卓机上都有文件管理的 app,一般打开 app 看到的最外层目录列表就属于所谓外部存储,用户可以在这个目录下的任一位置新建、删除文件。
如下是 Pixel 手机提供的文件管理 app,可以看到的目录都属于外部存储。
根据官方文档描述,当应用运行在 Android 4.4(API Level 19)或更高版本的 Android 上时,不需要申请读写外存权限。
另外因为各个安卓厂商可以定制自己的系统,所以外存路径访问的 API 返回的路径并不是唯一的。

假设: 外部存储的根目录路径为 path
Android SDK 提供的 API 如下:

getExternalFilesDir(String type)

获取的是 path/Android/data/<包名>/files 路径的 File 对象。注意这个方法需要指定一个参数 type,返回的 File 的路径是 path/Android/data/<包名>/files/<type>

getExternalCacheDir()

获取的是 path/Android/data/<包名>/cache 路径的 File 对象。

需要特别注意的是如果设备没有外部存储,以上外部存储访问的方法会返回 null。
当 app 删除时,这些目录以及下面的文件也会被删除。

4、注意事项

4.1 文件夹的构造

如果要在获取的路径下新建文件、文件夹等,要遵循一定的步骤。
例如某个路径为 :/data/data/<包名>/files/json,要创建这个路径,这里如果认为 json 是一个文件夹。方法是:

  • 构造路径:

    String targetFolderPath = getFilesDir() + "/json";
    

    注意 json 要带上分隔符。getFilesDir() 实际上返回的是 File 对象,不过这里应当可以自动转换为路径处理,如果要求一定是字符串的话,可以采用 getFilesDir().getAbsolutePath() 方法获取 File 对象的绝对路径。

  • 创建文件对象

    File targetFolder = new File(targetFolderPath);
    
  • 检测这个文件对象是否存在(路径是否存在,因为 getFilesDir() 一定是有这个路径的,所以就是检测这个路径下有没有名为 json 的文件夹)

    if(!targetFolder.exists()) {
       // 文件夹不存在时的逻辑
       // 一般是创建该文件夹
       targetFolder.mkDir();
    } else {
     //文件夹已经存在时的逻辑
     // 可以给出一些提示信息等
    }
    

4.2 文件的构造

路径实际上是文件名或者文件夹名的一种统称,可以指定特定的位置。但是文件和文件夹肯定是不同的,要建立文件,一般都要先有文件夹。还是以之前的文件夹构造为基础,如果在此基础上要建立文件,如 test.json
虽然文件夹和文件在 Java 中都作为 File 对象处理了,但是还是应当在变量名中区分这是文件还是文件目录,根据此调用对应的方法。

  • 文件路径的构造

    String targetFilePath = targetFolder + "/test.json";
    

    这里同样是直接使用了 File 对象。

  • 创建文件对象并检查是否存在

    File targetFile = new File(targetFilePath);
    if(!targetFile.exists()) {
       // 文件不存在时的逻辑
       // 一般是创建该文件
      try {
             targetFile.createNewFile();
      } catch (IOException e) {
             e.printStackTrace();
      }
    } else {
     //文件夹已经存在时的逻辑
     // 可以给出一些提示信息等
    }
    
    

    这里注意要处理可能出现的 IOException

4.3 为什么会有 IOException

如果需要创建文件,相当于是往存储空间中进行了写操作。如果没有权限的话,Java 会抛出异常。但是 WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE 这两个权限,如果是对外部存储的应用私有区域操作的话是不需要的(API Level 19 及以上)。
另外注意的是 Android 设备的外部存储概念不局限于 SD 卡,对于其他可能的外设,要实现读写,同样需要申请读写权限(需要用户同意)。

4.4 总结

总结一下,创建文件的基本方式是:
构造文件夹路径 -> 构造文件夹File对象 -> 检查 File 对象是否存在,不存在则创建文件夹 -> 借助之前的 File 对象构造文件路径 -> 构造文件 File 对象 -> 检测 File 对象是否存在,不存在则创建文件,并处理 IOException
另外既然以上提到的存储路径都是应用私有的,用 context 获取 API 进行操作也不难理解了。
这个流程是比较模块化的,完全可以、也很适合写一个工具类来处理 文件/文件夹 的构造流程。另外一点是关于异常的处理,可以打印一些自定义的日志等。毕竟如果真的发生了 IOException,打印 stackTrace 有些多此一举(无法避免异常)。
似乎 Kotlin 就有摒弃这种打印 stackTrace 的异常处理办法的潮流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值