数据存储之保存文件

Android使用一个文件系统,它类似于在其他平台上的基于磁盘的文件系统。接下来就开始学习如何在File APIs中使用Android文件系统读取和写入文件。

一个File对象是适合阅读或写大量的数据且一直都没有跳过周围。例如,它有益于图像文件或任何通过网络交换。

下面就开始学习如何在自己的应用程序中执行基本的与文件相关的任务。假定您熟悉基本的Linux文件系统和在java.io.中标准的文件输入/输出应用程序界面。

1、 选择内部或外部存储

所有的Android设备有两个文件存储区域:“内部”和“外部”存储。这些名字来自早期的Android,当大多数设备提供了内置的非易失性存储器(内部存储),再加上一个移动存储介质,如一个微型SD卡(外部存储)。一些设备将永久存储空间分成“内部”和“外部”分区,所以即使没有一个可移动存储介质,总有两个存储空间和API行为是相同的外部存储器是否可移动或不是。以下列表总结了关于每个存储空间的事实。

 

内部存储:                                                                                                                                            

 

•总是可用的。

•文件保存在这里时,只有你的应用程序在默认情况下才可以访问。

•当用户卸载应用程序时,系统会删除所有应用程序的文件从内部存储。

内部存储是最好的,当你想要确保无论是用户还是其他应用程序可以访问你的文件。

 

外部存储:

•并不总是可用,因为用户可以安装外部存储器作为USB存储而且还可以从设备中将其删除。

•,这是公开的所以文件保存在这里可能读并不受您的控制。

•当用户卸载应用程序,系统中移除你的应用程序的文件从这里只有如果你保存它们的目录从getExternalFilesDir()。

外部存储是文件的最佳场所,不需要访问限制和文件,以及您想要分享的其他的应用程序或允许用户访问计算机。

2、为外部存储获得权限

编写外部存储,你必须在你的manifest file中请求WRITE_EXTERNAL_STORAGE的权限:

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ...
</manifest>

目前,所有应用程序都能够读取外部存储没有特别许可。然而,这将改变未来的版本。如果你的应用需要读取外部存储器(但不是写信给它),那么您将需要声读外部存储(READ_EXTERNAL_STORAGE)许可。确保你的应用程序将继续按照预期工作,那么您现在应该在更改生效之前宣布本许可。
<manifest ...>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    ...
</manifest>
然而,如果你的应用程序使用外部存储器写权限,那么它也将隐式地允许读取外部存储。
你不需要任何权限保存文件的内部存储。你的应用程序在其内部存储目录内总是允许读和写文件。
3、将文件保存在内部存储
当保存一个文件到内部存储时,你可以获得适当的目录作为文件通过调用两个方法之一:
getFilesDir()
为你的应用程序返回一个文件代表一个内部目录,。
getCacheDir()
为你的应用程序的临时缓存文件返回一个文件代表一个内部目录,。一定要删除每个文件一旦不再需要和实现一个合理的大小限制为您使用的内存数量在任何给定的时间,比如1 mb。如果系统开始运行低存储,它将在没有警告的情况下可能删除您的缓存文件。
在其中一个目录中创建一个新的文件,你可以使用file()构造函数,传递文件提供了一个以上的方法,用于指定你的内部存储目录。例如:
File file = new File(context.getFilesDir(), filename);
或者,在你的内部目录内你可以调用openFileOutput()来获得一个FileOutputStream写入一个文件中。例如,下面是如何编写一些文本文件:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;

try {
  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
  outputStream.write(string.getBytes());
  outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}
或者,如果你需要缓存一些文件,那么你应该使用createTempFile()。例如,下面的方法是从一个URL中提取文件的名字并创建一个文件,这个名字在你的应用程序的内部缓存目录:
public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    catch (IOException e) {
        // Error while creating file
    }
    return file;
}
注意:你的应用程序内部存储目录指定的应用程序的包名称在一个特殊位置的Android文件系统。从技术上讲,另一个应用程序可以读取你的内部文件如果你设置文件模式是可读的。然而,其他应用程序也需要知道你的程序包名和文件名。其他应用程序不能浏览你的内部目录和没有读或写访问,除非您显式地设置文件是可读或可写的。所以在内部存储上只要你使用 MODE_PRIVATE对自己的文件,它们从来没有访问其他应用程序。

4、将文件保存在外部存储器
因为外部存储可能不可用,这样当用户安装存储到PC或已删除了SD卡,提供外部存储,你应该总是在验证卷可用之前访问它。您可以查询外部存储状态通过调用getExternalStorageState()。如果返回的状态等于媒体安装,然后你可以读和写你的文件。例如,下面的方法可有效地确定存储可用性:
/* Checks if external storage is available for read and write */
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;
}

虽然外部存储是可更改的由用户和其他应用程序,有两类文件你可能保存在这里:

公共文件

文件应该免费提供给其他应用程序和用户。当用户卸载应用程序,这些文件应该保持用户可用。

例如,照片捕捉到你的应用程序或其他下载的文件。

私人文件

文件,理所当然属于你的应用程序,应该删除当用户卸载应用程序。尽管这些文件在技术上可访问的用户和其他应用程序,因为它们在外部存储器,他们是文件,实际上不提供的价值,你的应用程序的用户外。当用户卸载应用程序,系统将删除所有的文件在您的应用程序的外部私人目录。

例如,额外的资源下载你的应用程序或临时的媒体文件。
如果你想在外部存储上保存公共文件,请使用getExternalStoragePublicDirectory()方法来获取一个文件代表适当的目录在外部存储器。该方法接受一个参数指定文件的类型,你想保存,这样他们可以逻辑组织与其他公共文件,比如目录音乐或目录图片。例如:
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;
}

如果你想保存的文件对于你的应用程序来讲都是私有的话,你可以获得适当的目录,只要你想便可通过调用getExternalFilesDir()并给它传递一个表示类型的目录名称。通过这种方式创建每个目录添加到父目录,用于封装所有应用程序的外部存储文件,当用户卸载应用程序时这些系统将删除。

例如,这里有一个方法可以用来创建个人相册的一个目录:


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()创建一个目录内的一个目录中删除是用来当用户卸载应用程序。如果这个文件是你储蓄要保持可供用户卸载后你的应用--例如当你的应用程序是一个照相机而且用户想要拍照片时,你应该使用getExternalStoragePublicDirectory()。

无论你使用getExternalStoragePublicDirectory()对文件共享或使用getExternalFilesDir()使文件到你的应用程序是私有的,重要的是你使用API提供的目录名称常量的类目录的照片。这些目录名称确保文件系统恰当的处理。例如,文件保存在目录铃声分类系统媒体扫描器作为铃声而不是音乐。

5、查询自由空间

如果你提前知道你节省多少数据,那么你可以找到足够的空间是否可以通过调用getFreeSpace()或getTotalSpace()不会导致一个IOException 。这些方法分别提供当前可用的空间和总空间存储卷。这些信息也很有用,以避免填充储存容量超过一定的阈值。

然而,系统通过getFreeSpace()并不保证你能写多少字节。如果返回的数量是几MB大小的超过你想保存的数据,或者如果文件系统是不到90%满,那么它可能是安全的进行。否则,你可能不应该写入存储。

6、删除一个文件
你应该总是删除一些你不再需要的文件。最简单的方法是删除一个文件打开的文件引用调用delete()本身。
myFile.delete();
如果文件是保存在内部存储器,你也可以通过上下文来定位和删除一个文件通过调用deleteFile():
myContext.deleteFile(fileName);

注意:当用户卸载应用程序时,Android系统删除以下:

a、你所有保存在内部存储器的文件

b、你使用getExternalFilesDir()保存到外部存储器里面的所有文件。

然而,你应该手动删除所有通过调用getCacheDir()创建的缓存文件,定期或是不定期的删除你不再需要的其他文件。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值