android 保存数据之文件存储

文件存储适合存放 从写入开始知道写完为止没有中断的大型数据,比如图片存储和网络交换文件存储。

==============================================关于“内部存储”和“外部存储”============start

在android早起的版本中,所有android设备都分两个存储区域:“内部存储”和“外部存储”。其中“内部存储”是永久固化的存储,是不可以手动移除的;“外部存储”是可以移除的例如一个SD卡。

一些设备会将固化到手机中的存储分为两个部分“内部存储”和“外部存储”,所以即使没有SD卡等可移除的“外部存储”,仍然有两个存储区域“内部存储”和“外部存储”,并且 API的行为是完全相同,无论是否有可以移除的“外部存储”。


“内部存储”的特性:

①永远可用,不可移除;

②默认情况下,只有你的App可以访问;

③当用户卸载你的App后,存储的文件会自动删除;

“外部存储”的特性:

①并不是一直可用,用户可以手动移除,也可以在设备上选择移除;

②存储在外部存储的文件所有app都可以访问;

③用户卸载App后不会删除保存到“外部存储”中的文件,除非是保存在getExternalFilesDir()得到的目录下的文件(也就是 /Android/data/" + context.getPackageName() +"/"目录下的文件)。

==============================================关于“内部存储”和“外部存储”============end

程序默认都具有访问“内部存储”的权限,无需申请;目前程序也默认具有读取“外部存储”的权限,但是为了以后的兼容,最好声明权限,当声明了

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

后,程序就同时获得了 读取“外部存储”的权限了。


===============================================“内部存储”的使用方法==============start

获得“内部存储”指定的存储目录文件有两个方法:

getFilesDir()这个方法返回你的app“内部存储”的目录文件,接着

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

就可以获得在“内部存储”中指定名称的文件了。

getCacheDir()这个是获得“内部存储”中作为app缓存的目录文件,一定要确保一旦不再使用缓存文件时要立即删除,并且要指定缓存目录的限制大小例如1M,当android运行在较低的存储情况下,会自动删除次目录下的文件而不会通知你。


下面看一下怎么方便的获得“内部存储”文件的写入流的方法(调用Context的openFileOutput() 方法,这个获得不是“内部存储”中的缓存目录getCacheDir()下的文件):


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();
}
在看一下怎么在“内部存储”的缓存目录下创建文件:

public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
	//第一个参数是文件名;第二个参数是文件后缀名传入null的话默认为.tmp
        file = File.createTempFile(fileName, null, context.getCacheDir());
    catch (IOException e) {
        // Error while creating file
    }
    return file;
}

需要注意的时,这个返回的文件的名是随机的,就是说一旦你失去这个文件的引用,那么你永远也不会再得到这个文件了,所以一旦不再使用的话要立即删除。

===============================================“内部存储”的使用方法==============end


==============================================="外部存储"的使用方法==============start

“外部存储”不同于“内部存储”,“外部存储”有可能不可用,比如设备连接了电脑并选择了读取SD卡,或者用户手动拔出了SD卡等。

在使用“外部存储”时首先要判断 “外部存储”是否可用,方法如下:

/* 检查外部存储是否可以读写 */
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;
}

虽然“外部存储”对于用户和其它app都是可以读写的,但是这里仍然有两种存储类型来供你选择:

public files 公共文件存储:

存储的文件对于用户和其他APP完全可见和可操作,你的app删除后缓存在此处的文件不会被删除,例如要缓存图片文件和下载的文件等。

private files 属于你app的文件存储:

虽然在技术上来说存储在这里的文件对于用户和其他app来说都是可见和可操作的(因为他们是外部存储的文件),但是存储在这里的文件在你的app之外切实不提供任何价值。当用户卸载你的APP后,此存文件会自动被删除。例如存放 你的app需要的额外下载资源文件、临时媒体文件等。


----------------------------------------------------------------------------------------------------------------------

下面说怎么在这两种类型的“外部存储”区域创建文件:

public files 存储,调用 getExternalStoragePublicDirectory() 方法来获得外部存储设备上的相应目录文件,该方法需要一个参数指定的文件类型来确保存储的文件可以在逻辑上与其他的公共文件组织起来,比如DIRECTORY_MUSIC 来声明你缓存的是音乐文件,那么android会把你的文件保持到“外部存储”中的 Music/你指定的名称/下面。

    代码实现:

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 files 存储,getExternalFilesDir()方法并传入一个 目录名称,每一个创建在此处的文件都存放在 "/Android/data/" + context.getPackageName() +"/"目录下,

代码如下:

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;
}

在这个方法中,context.getExternalCacheDir() 是 2.2 及以上才支持,如果是2.2及以下 就手动拼出目录:"/Android/data/" + context.getPackageName() +"/"。


===============================================================现在说说怎么获得存储剩余空间=======start====


为了避免在操作文件时导致 IOException,你需要调用File的   getFreeSpace()getTotalSpace()方法来查询剩余空间是否够用。

然而,该系统并不能保证你可以写多少字节表示由getFreeSpace()。如果返回的数字是几MB的大小超过您想要的数据保存,或者如果文件系统是小于90%,那么它可能是安全的继续。否则,你可能不应该写入到存储。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值