访问应用专属文件(二)|Android开发-存储系列

835 阅读3分钟

这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战

介绍

在大多数就情况下我们的APP会创建其他应用不需要访问的文件。系统提供以下位置,用于存储此类应用专属文件:

  • 内部存储空间目录:这些目录既包括用于存储持久性文件的专属位置,也包括用于存储缓存数据的其他位置。系统会阻止其他应用访问这些位置,并且在 Android 10(API 级别 29)及更高版本中,系统会对这些位置进行加密。这些特征使得这些位置非常适合存储只有应用本身才能访问的敏感数据。
  • 外部存储空间目录:这些目录既包括用于存储持久性文件的专属位置,也包括用于存储缓存数据的其他位置。虽然其他应用可以在具有适当权限的情况下访问这些目录,但存储在这些目录中的文件仅供您的应用使用。如果您明确打算创建其他应用能够访问的文件,您的应用应改为将这些文件存储在外部存储空间的共享存储空间MediaStore部分。

注:如果应用被卸载,系统会移除保存在应用专属存储空间中的文件。

内部存储空间访问

对于每个应用,系统都会在内部存储空间中提供目录,应用可以在该存储空间中整理其文件。一个目录专为应用的持久性文件而设计,而另一个目录包含应用的缓存文件。不需要任何系统权限即可读取和写入这些目录中的文件。

其他应用无法访问存储在内部存储空间中的文件。这使得内部存储空间适合存储其他应用不应访问的应用数据,写入前需要查询设备上的可用空间。

private long queryMemory(){
    long availableBytes = 0;
    StorageManager storageManager = getApplicationContext().getSystemService(StorageManager.class);
    UUID appSpecificInternalDirUuid = null;
    try {
        appSpecificInternalDirUuid = storageManager.getUuidForPath(getFilesDir());
        availableBytes = storageManager.getAllocatableBytes(appSpecificInternalDirUuid);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return availableBytes;
}

访问持久性文件

访问和存储文件

File file = new File(context.getFilesDir(), filename);

使用信息流存储文件

除使用 File API 之外,您还可以调用 openFileOutput() 获取会写入 filesDir 目录中的文件的 FileOutputStream

String filename = "myfile";
String fileContents = "Hello world!";
try (FileOutputStream fos = this.openFileOutput(filename, this.MODE_PRIVATE)) {
    fos.write(fileContents.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
    e.printStackTrace();
}

使用信息流访问文件

String filename = "myfile"; 
FileInputStream fis = context.openFileInput(filename);
InputStreamReader inputStreamReader =
        new InputStreamReader(fis, StandardCharsets.UTF_8);
StringBuilder stringBuilder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(inputStreamReader)) {
    String line = reader.readLine();
    while (line != null) {
        stringBuilder.append(line).append('\n');
        line = reader.readLine();
    }
} catch (IOException e) {
    // Error occurred when opening raw file for reading.
} finally {
    String contents = stringBuilder.toString();
}

查看文件列表

调用 fileList()获取包含 filesDir 目录中所有文件名称的数组

Array<String> files = context.fileList();

创建嵌套目录

File directory = context.getFilesDir();
File file = new File(directory, filename);

创建缓存文件

此缓存目录旨在存储应用的少量敏感数据。如需确定应用当前可用的缓存空间大小,请调用 getCacheQuotaBytes()

创建

File.createTempFile(filename, null, context.getCacheDir());

访问

//当设备的内部存储空间不足时,Android 可能会删除这些缓存文件以回收空间。因此,需要在读取前检查缓存文件是否存在。
File cacheFile = new File(context.getCacheDir(), filename);

移除缓存文件

context.deleteFile(cacheFileName);