Android存储

本文详细介绍了Android应用中文件存储的方式,包括内部存储(internal storage)和外部存储(external storage)的区别及使用方法。内部存储适用于需要保护的数据,而外部存储则适合于共享文件。文中还介绍了如何检查外部存储的状态及文件存储的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SharedPreferences

SharedPreferences的获取可以分为两种方式:
如果一个App需要很多SharedPreferences文件,并以名字作为区分的话,可以使用getActivity.getSharedPreferences(String name, int mode);方法指定名称和打开模式。

如果创建了一个MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE 模式的shared preference文件,则其他任何app均可通过文件名访问该文件。

另外一种方式是只需要一个SharedPreferences文件的话,可以直接使用getActivity.getPreference(int mode);方法打开默认的SharedPreferences文件。
这两个方法可以在app中通过任何一个Context执行。


文件存储

所有的Android设备均有两个文件存储区域:“internal”与“external” ,两者区别如下:

  • Internal storage:

    总是可用的
    这里的文件默认只能被我们的app所访问。
    当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
    Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。

  • External storage
    并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
    是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
    当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
    External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。

Tip: 尽管app是默认被安装到internal storage的,我们还是可以通过在程序的manifest文件中声明android:installLocation 属性来指定程序安装到external storage。当某个程序的安装文件很大且用户的external storage空间大于internal storage时,用户会倾向于将该程序安装到external storage。更多安装信息见App Install Location。

保存到Internal storage

当保存文件到internal storage时,可以用下面两种方式之一来获取合适的目录作为File的对象

  1. getFileDir():返回一个File,代表了我们app的Internal目录
  2. getCacheDir():返回一个File,代表了我们app的Internal缓存目录。
    可以使用File()构造器在那些目录下面创建一个新文件,如下
File file = new Filecontext.getFileDir(), fileName);

同样,也可以执行openFilOutputStream用于写文件到Internal目录。如下:

String fileName = "myFlie"
String string = "hello world";
FileOutputStream outputStream;
try{
    outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
    outputStream.write(string.getBytes());
    outputStream.close();
} catch(Exception e){
    e.printStrackTrace();
}

如果需要缓存一些文件,可以使用creatTempFile()。例如:下面的方法从URL中抽取了一个文件名,然后再在程序的internal缓存目录下创建了一个以这个文件名命名的文件。

public File getTempFile(Context context, String uri){
    File file;
    try{
        String fileName = Uri.pares(url).getLastPathSegment();
        file = File.creatTempFile(fileName, null, context.getCacheDir();
    } catch(IOException e){
        e.printStrackTrace();
    }
    return file;
}

保存到External storage
因为external storage可能是不可用的,比如遇到SD卡被拔出等情况时。因此在访问之前应对其可用性进行检查。我们可以通过执行 getExternalStorageState()来查询external storage的状态。若返回状态为MEDIA_MOUNTED, 则可以读写。示例如下:

public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

想要将文件以public形式保存在external storage中,请使用getExternalStoragePublicDirectory()方法来获取一个 File 对象,该对象表示存储在external storage的目录。这个方法会需要带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES. 如下:

public File getAlbumStorageDir(String albumName) {
    // Get the directory for the user's public pictures directory.
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

想要将文件以private形式保存在external storage中,可以通过执行getExternalFilesDir() 来获取相应的目录,并且传递一个指示文件类型的参数。每一个以这种方式创建的目录都会被添加到external storage封装我们app目录下的参数文件夹下(如下则是albumName)。这下面的文件会在用户卸载我们的app时被系统删除。如下示例:

public File getAlbumStorageDir(Context context, String albumName) {
    // Get the directory for the app's private pictures directory.
    File file = new File(context.getExternalFilesDir(
            Environment.DIRECTORY_PICTURES), albumName);
    if (!file.mkdirs()) {
        Log.e(LOG_TAG, "Directory not created");
    }
    return file;
}

请记住,getExternalFilesDir() 方法会创建的目录会在app被卸载时被系统删除。如果我们的文件想在app被删除时仍然保留,请使用getExternalStoragePublicDirectory().

查询剩余空间
如果事先知道想要保存的文件大小,可以通过执行getFreeSpace() or getTotalSpace() 来判断是否有足够的空间来保存文件,从而避免发生IOException。那些方法提供了当前可用的空间还有存储系统的总容量。

然而,系统并不能保证可以写入通过getFreeSpace()查询到的容量文件, 如果查询的剩余容量比我们的文件大小多几MB,或者说文件系统使用率还不足90%,这样则可以继续进行写的操作,否则最好不要写进去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值