移动设备的文件系统是在闪存中组织、存储和命名数据的方式。根据Android Developers,2026,移动操作系统使用层次化目录结构,每个应用程序在隔离的沙箱中运行。这种架构防止未经授权的数据访问,并确保在同时运行多个应用程序时系统稳定运行。
要点
文件系统是操作系统的软件组件,管理数据在物理介质上的写入、读取和组织方式。在移动设备上,文件系统执行关键功能:管理闪存空间、基于权限控制文件访问、记录更改以便故障后恢复,以及根据 NAND 闪存的特性优化写入。
与桌面操作系统不同,移动文件系统的设计考虑了闪存有限的写入周期资源。NAND 单元能承受有限的擦除操作次数——TLC 和 MLC 存储器分别为 3,000 到 10,000 次。为延长存储设备寿命,文件系统采用磨损均衡(wear leveling)机制和 TRIM 命令。三星专门为闪存开发的 F2FS 考虑了 NAND 阵列的几何结构,以最小化碎片化和块擦除操作次数的方式放置数据。
现代移动设备使用多种文件系统的组合。内部存储器(/data 分区)在 Android 上格式化为 EXT4 或 F2FS,在 iOS 上格式化为 APFS。SD 卡传统上使用 exFAT 以支持大于 4 GB 的文件,或 FAT32 以获得最大兼容性。Android 上的 /system 分区通常以只读方式挂载,使用 EXT4 或 EROFS(增强型只读文件系统)——华为为减小系统分区大小而开发的压缩文件系统。
目录层次结构 Android 基于根目录为 / 的 Linux 结构。每个分区都有自己的文件系统、访问权限和用途。应用程序只能访问有限的目录集——其余受 root 权限保护。
| 路径 | 分区 | 文件系统 | 应用程序访问 |
|---|---|---|---|
| /data | Userdata | F2FS / EXT4 | 仅自己的沙箱 |
| /system | System | EROFS / EXT4 | 仅读取(root) |
| /sdcard | External | exFAT / FAT32 | 需授权 |
| /cache | Cache | EXT4 | 仅 root |
| /vendor | Vendor | EROFS / EXT4 | 仅读取(root) |
/data 分区是存储用户数据、已安装应用程序及其设置的主要分区。每个应用程序在路径 /data/data/<package_name>/ 下获得自己的目录。在此目录内,系统自动创建子目录:files/ 用于应用程序文件,cache/ 用于临时文件,databases/ 用于 SQLite 数据库,shared_prefs/ 用于 SharedPreferences。对此目录的访问权限在安装应用程序时设置,没有 root 权限无法更改。大多数现代设备上的 /data 分区使用 F2FS 格式化,与 EXT4 相比,随机写入速度提高高达 40%。
/system 分区包含操作系统、系统应用程序和库。此分区以只读方式挂载,以防止意外或恶意修改系统文件。在具有 Android 10+ 和 Project Treble 的设备上,/system 分区是动态的,可以通过 OTA 包更新,无需完全重新刷机。对于应用程序,/system 分区不可访问——尝试写入会导致 SecurityException。但是,如果应用程序具有相应权限,可以读取 /system 中的某些文件,例如系统字体和配置文件。
/sdcard 挂载点是指向模拟或物理外部存储分区的符号链接。在没有 SD 卡的设备上,/sdcard 指向 /data 内用于共享访问的子分区。当设备通过 MTP 协议连接到计算机时,此分区对用户可见。应用程序通过 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限访问 /sdcard,从 Android 10 开始通过 Scoped Storage 使用 MediaStore API。/sdcard 的大小通常占设备闪存总容量的 60–80%,其余保留给 /data 分区。
在 iOS 中,文件系统通过应用程序的沙箱容器组织。每个应用程序获得一个隔离的目录,其访问在 XNU 内核级别受限。用户分区使用 iOS 10.3 中引入的 APFS(Apple 文件系统)。APFS 支持快照、文件克隆和文件级加密,使其成为移动设备的最佳选择。
iOS 沙箱容器包括四个主要目录:Documents、Library、tmp 和 SystemData。每个目录都有自己的备份策略、数据保留期限和访问级别。Documents 自动包含在 iCloud 和 iTunes 备份中。Library 包含子目录 Caches(不备份)、Preferences(备份)和 Application Support(备份)。tmp 目录用于临时文件——iOS 在空间不足时可以删除它们,且不包含在备份中。SystemData 由系统本身使用,应用程序通过标准 API 无法访问。
let fm = FileManager.default
let documents = fm.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let caches = fm.urls(
for: .cachesDirectory,
in: .userDomainMask
).first!
let appSupport = fm.urls(
for: .applicationSupportDirectory,
in: .userDomainMask
).first!
沙箱容器的每个目录都有自己的保护类别(protection class)。iOS 支持四种类别:Complete Protection(设备锁定时文件不可访问)、Protected Unless Open(已打开的文件在锁定时可访问)、Protected Until First User Authentication(首次解锁后可访问)和 No Protection(设备启动后始终可访问)。默认情况下,Documents 和 Library 中的所有文件都获得 Complete Protection 类别,确保用户数据的最大保护。创建文件时,如果后台应用程序需要在设备锁定时访问数据,可以显式指定其他保护类别。
移动设备上文件的访问管理是 Android 和 iOS 之间的关键区别。Android 使用经典的 Linux 访问权限模型(读取、写入、执行),并扩展以隔离应用程序。iOS 采用更严格的沙箱模型,每个应用程序在隔离的容器中运行,没有特殊机制就无法访问其他应用程序的文件。
在Android上,每个应用程序以单独的 UID(用户 ID)运行。应用程序在其沙箱中创建的所有文件都属于此 UID,对其他应用程序不可见。要访问共享目录(外部存储),应用程序必须请求 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限。从 Android 11 开始,权限必须在运行时请求,targetSdkVersion 30+ 的应用程序要访问其他应用程序的文件必须使用 SAF。违反权限模型会导致 SecurityException,由标准 try-catch 块处理。Google Play 在发布前会自动检查应用程序是否符合权限政策。
if (ContextCompat.checkSelfPermission(
context,
Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
REQUEST_CODE
)
}
iOS 沙箱在 XNU 内核级别实现,不允许应用程序离开其容器。即使应用程序通过 Document Picker 获取外部文件的 URI,操作系统也会在应用程序容器中创建临时副本,而不是提供对原始文件的直接访问。对于应用程序之间的文件共享,iOS 使用 Share Sheet 和 UIActivityViewController 机制,将文件从一个应用程序的容器复制到另一个应用程序的容器。为了安全存储凭据(令牌、密码、密钥),iOS 提供 Keychain——一个在内核级别对系统可用的加密存储库。Keychain 不是沙箱容器的一部分,由独立的 securityd 守护进程管理,即使在应用程序受损时也能提供额外的保护层。
文件系统的选择直接影响数据存储的性能和可靠性。每个文件系统都有自己的架构、优化和限制。开发人员了解这些差异有助于预测应用程序在不同设备上的行为。
开发应用程序时,请注意不同的文件系统具有不同的文件名长度限制(EXT4 和 F2FS 为 255 字节,APFS 为 255 个 Unicode 字符)、最大文件大小和特殊字符支持。例如,APFS 允许文件名中的 Unicode 字符,包括表情符号,而 EXT4 限于 ASCII。如果应用程序创建不同语言名称的文件,请在所有目标设备上测试——在 APFS 上正确创建的文件名可能在 EXT4 上被截断。
可靠地使用移动设备的文件系统需要遵循几个关键规则。这些规则基于对开发人员典型错误的分析和官方文档的建议。
context.filesDir,iOS 上的 NSSearchPathForDirectoriesInDomains。硬编码路径在操作系统版本和设备之间会变化File.getUsableSpace() 和 iOS 上的 URLResourceValues.volumeAvailableCapacityKey。如果可用空间不足,提醒用户isExcludedFromBackup 从备份中排除缓存。在 Android 上,临时文件优先使用 cacheDir特别关注跨平台差异。Android 上的文件路径使用正斜杠构建(/data/data/.../files/),iOS 上通过 URL 方案(file:///var/mobile/.../Documents/)。如果您的应用程序使用跨平台框架(Flutter、React Native、Kotlin Multiplatform),通过平台适配器统一文件操作。例如,Flutter 提供 path_provider 包,无需编写平台相关代码即可在两个平台上返回正确的 Documents 或 filesDir 路径。永远不要使用字符串操作连接路径——使用正确处理不同平台上分隔符的 File.join() 或 URL.appendingPathComponent()。
常见问题
在 modern Android 设备(11+)上,/data 分区使用 F2FS。在旧设备上——EXT4。/system 分区使用 EROFS 或 EXT4。SD 卡根据容量格式化为 exFAT 或 FAT32。
APFS 支持快照、文件克隆、文件级加密和校验和。EXT4 具有日志记录和更广泛的兼容性。APFS 针对 SSD 进行了优化,EXT4 是通用文件系统。
使用 FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)。该方法返回 URL 数组,第一个元素是应用程序沙箱容器的主 Documents 目录。
Scoped Storage 是在 Android 10 中引入的访问模型,限制直接访问文件系统。应用程序未经许可只能读取自己的文件。访问共享媒体文件使用 MediaStore API。
exFAT 更适合容量超过 32 GB 的 SD 卡,因为它支持大于 4 GB 的文件。FAT32 提供与旧设备的最大兼容性,但将文件大小限制为 4 GB。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。