查看原文
其他

Android 文件系统小记

麦客奥德彪 郭霖
2024-08-23


/   今日科技快讯   /

近日,市场调研机构TrendForce集邦咨询最新研报显示,由于AI需求大幅升温,最近两季AI服务器相关客户向供应商进一步要求加单Enterprise SSD(企业级固态硬盘)。上游供应商为了满足SSD在AI应用上的供给,加速制程升级,开始规划推出2YY产品,预期于2025年量产。该机构预估,今年AI相关SSD采购容量将超过45EB,未来几年,AI服务器有望推动SSD需求年增率平均超过60%,而AI SSD需求在整个NAND Flash(闪存)的占比有机会自2024年的5%,上升至2025年的9%。

/   作者简介   /

本篇文章转自麦客奥德彪的博客,文章主要分享了Android文件系统的相关内容,相信会对大家有所帮助!

原文地址:
https://juejin.cn/post/7400317170083463195

/   前言   /

Android 的文件系统结构主要分为内部存储、外部存储和特殊目录。每个部分都有特定的用途和访问权限。以下是详细介绍。

/   内部存储   /

内部存储是设备的内置存储,专门用于保存应用的私有数据。每个应用都有自己的内部存储空间,其他应用不能访问。

路径

/data/data/<package_name>/

特点

  • 私有性:数据对应用本身可见,其他应用无法访问。
  • 安全性:在设备被擦除或应用被卸载时,这些数据会被删除。
  • 权限:不需要申请额外权限。

常用路径和 API

文件存储路径

  • 路径:/data/data/<package_name>/files/
  • API:Context.getFilesDir()
  • 使用场景:存储应用的配置文件、用户数据等私有文件。

File filesDir = context.getFilesDir();
File myFile = new File(filesDir, "myfile.txt");

缓存存储路径

  • 路径:/data/data/<package_name>/cache/
  • API:Context.getCacheDir()
  • 使用场景:存储临时数据或缓存文件,系统在需要时可以清除这些文件。

File cacheDir = context.getCacheDir();
File tempFile = new File(cacheDir, "tempfile.tmp");

代码缓存路径

  • 路径:/data/data/<package_name>/code_cache/
  • API:Context.getCodeCacheDir()
  • 使用场景:存储优化后的代码或编译后的代码缓存。

File codeCacheDir = context.getCodeCacheDir();

内部存储的使用

// 获取内部存储目录
File internalDir = context.getFilesDir(); // /data/data/<package_name>/files

// 写文件
File file = new File(internalDir, "example.txt");
try (FileOutputStream fos = new FileOutputStream(file)) {
    fos.write("Hello, World!".getBytes());
} catch (IOException e) {
    e.printStackTrace();
}

// 读文件
try (FileInputStream fis = new FileInputStream(file)) {
    byte[] data = new byte[(int) file.length()];
    fis.read(data);
    String content = new String(data, "UTF-8");
    System.out.println(content);
} catch (IOException e) {
    e.printStackTrace();
}

/   外部存储   /

外部存储是设备的共享存储区域,可以是内置存储(如主存储)或可移动存储(如 SD 卡)。外部存储可以被多个应用访问,但需要申请相应的权限。

公共外部存储:用于存放用户可见的文件,如图片、音频、视频等。

路径:/storage/emulated/0/ 或 Environment.getExternalStoragePublicDirectory()

特点:

  • 数据对用户和其他应用可见。
  • 用户卸载应用时,这些数据不会被删除。
  • 需要申请读写权限。

应用专属外部存储:用于存放应用的私有数据,但位于外部存储中。

路径:/storage/emulated/0/Android/data/<package_name>/

特点:

  • 数据对应用本身可见,其他应用无法访问。
  • 应用卸载时,这些数据会被删除。
  • 需要申请读写权限。

常用路径和 API

公共外部存储路径

  • 路径:/storage/emulated/0/ 或特定的公共目录,如Downloads,Pictures,DCIM,Music,Movies
  • API:Environment.getExternalStoragePublicDirectory(String type)
  • 使用场景:存储用户可见的文件,如下载的文件、媒体文件等。

File publicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File publicFile = new File(publicDir, "downloadedfile.txt");

应用专属外部存储路径

  • 路径:/storage/emulated/0/Android/data/<package_name>/files/
  • API:Context.getExternalFilesDir(String type)
  • 使用场景:存储应用的私有文件,用户可以通过文件管理器访问,应用卸载时这些文件会被删除。

File appSpecificDir = context.getExternalFilesDir(null);
File appSpecificFile = new File(appSpecificDir, "appfile.txt");

应用专属外部缓存路径

  • 路径:/storage/emulated/0/Android/data/<package_name>/cache/
  • API:Context.getExternalCacheDir()
  • 使用场景:存储临时缓存文件,系统在需要时可以清除这些文件。

File externalCacheDir = context.getExternalCacheDir();
File tempExternalFile = new File(externalCacheDir, "tempfile.tmp");

外部存储的使用

// 获取公共外部存储目录
File publicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

// 获取应用专属外部存储目录
File privateDir = context.getExternalFilesDir(null);

// 写文件到公共外部存储
File publicFile = new File(publicDir, "public_example.txt");
try (FileOutputStream fos = new FileOutputStream(publicFile)) {
    fos.write("Hello, Public World!".getBytes());
} catch (IOException e) {
    e.printStackTrace();
}

// 写文件到应用专属外部存储
File privateFile = new File(privateDir, "private_example.txt");
try (FileOutputStream fos = new FileOutputStream(privateFile)) {
    fos.write("Hello, Private World!".getBytes());
} catch (IOException e) {
    e.printStackTrace();
}

// 动态申请权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
          new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
          REQUEST_WRITE_STORAGE);
}

/   特殊目录   /

Android 提供了一些特殊的目录,用于存储特定类型的数据,如缓存、临时文件等。

缓存目录:用于存储临时缓存数据,系统在需要空间时可以自动清理这些数据。

  • 内部缓存:context.getCacheDir(),路径为 /data/data/<package_name>/cache/
  • 外部缓存:context.getExternalCacheDir(),路径为 /storage/emulated/0/Android/data/<package_name>/cache/

代码缓存目录:用于存储应用的优化代码或其他编译后的代码。

路径:context.getCodeCacheDir()

临时文件目录:用于存储临时文件,开发者需要自行管理这些文件。

路径:context.getExternalFilesDir(Environment.DIRECTORY_TEMPORARY)(API 级别 30+)

缓存文件被称为特殊目录是因为: context.getCacheDir() 被称为特殊目录主要是因为它用于存储应用的临时缓存数据,并且具有一些独特的特性和用途。以下是详细的解释:

特殊性和用途

临时性:

  • 自动管理:缓存目录中的文件是临时文件,系统在需要空间时会自动清理这些文件。
  • 清除策略:当设备存储空间不足时,系统可能会删除缓存目录中的文件以释放空间。开发者无需手动管理这些文件的生命周期。

私有性:

应用专有:缓存目录是应用私有的,其他应用无法访问这些文件。这与其他内部存储路径(如 context.getFilesDir())一样,提供了安全性和数据隔离。

不需要权限:

默认可用:与内部存储中的其他路径类似,访问缓存目录不需要申请任何额外权限。这使得缓存操作简单且高效。

使用场景:

  • 临时存储:适用于存储临时数据,如图片缓存、网络请求缓存等。缓存文件不需要持久保存,可以随时重新生成。
  • 快速访问:由于缓存目录通常存储在设备的内部存储中,因此访问速度较快,适合需要高效读写操作的临时数据。

特殊目录总结

  • 自动管理:系统自动清理,开发者无需手动管理。
  • 私有安全:仅对应用本身可见,确保数据安全。
  • 无需权限:简化了开发流程。适用场景:临时文件存储、缓存数据等。

访问权限

内部存储:不需要额外权限。

外部存储:

  • 读写公共外部存储:需要申请 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限。
  • 应用专属外部存储:从 Android 10 开始,应用可以不需要申请权限直接访问自己的专属外部存储。

/   总结   /

内部存储:私有、安全、无需权限。
外部存储:分为公共和专属,公共需要权限,专属不需要权限(Android 10+)。
特殊目录:用于缓存和临时数据,系统自动管理部分目录。

推荐阅读:
我的新书,《第一行代码 第3版》已出版!
原创:写给初学者的Jetpack Compose教程,高级Layout
Android帝国之日志系统--logd、logcat

欢迎关注我的公众号
学习技术或投稿


长按上图,识别图中二维码即可关注
继续滑动看下一个
郭霖
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存