原文地址:
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+)。
特殊目录:用于缓存和临时数据,系统自动管理部分目录。