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)
  • 使用场景:存储应用的私有文件,用户可以通过文件管理器访问,应用卸载时这些文件会被删除。
应用专属外部缓存路径
  • 路径:/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+)。
特殊目录:用于缓存和临时数据,系统自动管理部分目录。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容