您现在的位置是:首页 >技术杂谈 >Android App专属文件(app-specific files)存储网站首页技术杂谈

Android App专属文件(app-specific files)存储

ShawnRacine 2023-06-14 08:00:03
简介Android App专属文件(app-specific files)存储

前言

有很多场景,我们的App需要创建一些其他App不需要访问、不应该访问的文件,系统提供了一下两种App专属(app-specific)存储目录:

1、内部存储目录(Internal storage directories):

指的是:/data/user/0/packagename/…目录
该目录提供两个目录:一个专门存储持久化文件(getFileDir),一个存储缓存文件(getCacheDir)。
此目录其他App无法访问。

2、外部存储目录(External storage directories):

指的是:/storage/emulated/0/Android/data/packagename/…目录
该目录也提供两个目录:一个专门存储持久化文件(getFileDir),一个存储缓存文件(getCacheDir)。
此目录旨在存储本应用使用的文件,如果需要存储一些可供其他应用访问的共享文件,请使用可共享存储技术(Media content、Documents and other files、Datasets)

App专属存储目录,随着App卸载,会被删除。

一、访问内部存储(Access From Internal Storage)

注意:这个目录往往比较小。内部存储(Internal storage)只提供有限的空间给App专属数据。
Keep in mind, however, that these directories tend to be small. Before writing app-specific files to internal storage, your app should query the free space on the device.
How much space does your data require?
Internal storage has limited space for app-specific data. Use other types of storage if you need to save a substantial amount of data.

1、getFilesDir:访问持久化文件(Access persistent files)

指的是:/data/user/0/packagename/files/…目录

1.1、访问和存储文件(context.getFilesDir())

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

1.2、使用流存储文件(context.openFileOutput())

文件会存储到getFileDir()目录下

String filename = "myfile";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
    fos.write(fileContents.toByteArray());
}

1.3、使用流访问文件(context.openFileInput())

访问getFileDir()目录下的文件

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('
');
        line = reader.readLine();
    }
} catch (IOException e) {
    // Error occurred when opening raw file for reading.
} finally {
    String contents = stringBuilder.toString();
}

1.4、查看文件列表(context.fileList())

查看getFileDir()目录下的所有文件

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

2、getCacheDir:创建缓存文件(Create cache files)

指的是:/data/user/0/packagename/cache/…目录

File.createTempFile(filename, null, context.getCacheDir());
File cacheFile = new File(context.getCacheDir(), filename);

二、访问外部存储(Access From External Storage)

Android 4.4及以后,App不再需要请求存储权限就可以访问外部存储中的App专属目录

Android 10(API level 29) 及以后,App默认开启作用域存储模式,App将不能访问非当前应用专属的路径。
只能访问外部存储上当前App专属路径,和App已经创建的指定媒体类型(MediaStore APIs)

On Android 4.4 (API level 19) or higher, your app doesn’t need to request any storage-related permissions to access app-specific directories within external storage. The files stored in these directories are removed when your app is uninstalled.

Scoped storage
To give users more control over their files and to limit file clutter, apps that target Android 10 (API level 29) and higher are given scoped access into external storage, or scoped storage, by default. Such apps have access only to the app-specific directory on external storage, as well as specific types of media that the app has created.

1、getExternalFilesDir:访问持久化文件(Access persistent files)

指的是:/storage/emulated/0/Android/data/packagename/files/…目录

File appSpecificExternalDir = new File(context.getExternalFilesDir(null), filename);

pass null into getExternalFilesDir(). This returns the root app-specific directory within external storage.

2、getExternalCacheDir:创建缓存文件(Create cache files)

指的是:/storage/emulated/0/Android/data/packagename/cache/…目录

File externalCacheFile = new File(context.getExternalCacheDir(), filename);

3、Environment.getExternalStorageState:检查外部存储是否可用

// Checks if a volume containing external storage is available
// for read and write.
private boolean isExternalStorageWritable() {
    return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}

// Checks if a volume containing external storage is available to at least read.
private boolean isExternalStorageReadable() {
     return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ||
            Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);
}
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。