Android文件存储全攻略

一个File对象可用于读写大量的数据,比如,它可以用来保存图片和从网络获取到的数据。

选择内部(Internal)或外部(External)存储

所有的Android设备都有俩个文件存储位置,"内部(Internal)"“外部(External)”

Internal storage(内部存储)使用介绍:
  • 一直存在,随时可以使用。
  • 存储在此处的文件默认只能被你的App获取。
  • 当用户卸载当前的App,系统将会删除当前App存储的所有文件。

如果你不想用户或者其他的App获取到你的文件,可以选择使用**Internal storage(内部存储)**去存储文件
#### 外部存储(External storage)使用介绍:

  • 不是随时都能使用,因为如果用户移除外置的SD卡,或者USB连接等一些因素导致SD卡从设备上移除。
  • 所有人都能从External storage中读取数据,所以数据存储到这里,不安全。
  • 当用户卸载了你的App,系统只会清除掉**getExternalFilesDir()目录下的数据。
    如果你想其他的App获取到你的数据,或者允许用户连接到电脑后读取数据,可以选择使用
    外部存储(External storage)**去存储。

小知识:应用默认都安装在internal storage,我们可以在manifest中配置android:installLocation来设置你的App安转在internal storage还是External Storage

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:installLocation="preferExternal"
    ... >

目前来说,仅仅读取外部SD卡不需要加入任何权限,但是,在以后的版本中,谷歌表示会对此作出改变。所以谷歌建议,即使仅仅是读取外部SD卡,也加入READ_EXTERNAL_STORAGE,以免变动后受到影响。
但是,如果申明了WRITE_EXTERNAL_STORAGE,同时也获得了READ_EXTERNAL_STORAGE权限。

注意:如果你要使用internal storage存储文件,则不需要申明任何权限,直接使用即可。

存储文件到Internal Storage

可以通过俩个方法存储获取到Internal Storage的目录
**getFilesDir()**返回你的App的内部存储目录。
**getCacheDir()**返回你的App的内部缓存文件目录,在这个目录下数据,如果不需要了要及时的清楚,因为如果这个目录中的数据大于的1MB, 系统会自动清除里面的数据,而不会有任何提醒。

可以通过如下代码来创建一个文件在Internal Storage中

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()**方法。比如,下面的这个方法是从一个UR中抽取一个文件名称,并且创建文件在你的App所拥有的内部存储中。

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设置为readable,那么,另外的App也会访问到你的应用的内存存储文件,但是,其他的App需要知道你的应用的包名和文件名称,如果你不把文件权限设置为 readable 或者writable,其他的App默认是访问不到你的内部存储文件的。所以 ,只要你把内存储存中的文件模式设置为MODE_PRIVATE,其他App是不能获取到该文件的。

存储文件到External Storage

由于外部存储有时是不能使用的,所以在使用External Storage前,必须要判断是否可用。通常通过getExternalStorageState(). 来判断,如果返回的结果为MEDIA_MOUNTED,则你可以在External Storage中存储你的文件。以下是谷歌给出的判断External Storage是否可用的示例代码:

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

尽管外部存储的文件可以被用户或者其他的App操作,但是external storage的优势还是很明显的:

  1. external storage的文件可以被用户或其他App使用,当用户卸载了你的app,这些文件还是应该保留下来,比如,用过你的App拍的照片,或者下载的文件。
  2. 但你的App卸载的时候,一些属于你的App的数据应该被删除,尽管用户和其他App可以访问到这些数据,但是这些文件不用再为用户活其他App提供数据,所以,当用户下载App,所有在你App私有目录下的文件都会被删除。

如果你要在external storage上存储一个共享的文件,**getExternalStoragePublicDirectory() **可以获取到你的应用在external storage上的目录,这个方法中参数是为可说明你存储的文件的类型,以便于系统能够组织化的管理这些共享的数据,比如参数可以为DIRECTORY_MUSIC 或者DIRECTORY_PICTURES
,下面是谷歌给出我i示例代码:

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

如果你想存储的数据是自己App私有,你可以通过**getExternalFilesDir()**方法获取,当你的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(null),在参数里面传入null来获取到一你的App在external storage.中的私有根目录。
通过getExternalFilesDir()方法获取到目录,在用户卸载App时会被删除,如果你不想被删除,可以通过
getExternalStoragePublicDirectory().方法获取到的目录来存储数据。
无论你是通过
getExternalStoragePublicDirectory()方法还是getExternalFilesDir()方法来存数数据,目录名称还是非常重要的,谷歌建议使用API提供的常量目录名称
,比如
DIRECTORY_PICTURES
。因为,这些目录下将会被系统分类进行管理,举例来说,如果你使用DIRECTORY_RINGTONES 目录,则系统将会把它分类到来电铃声的选择项中。

查询硬盘的可存储空间

如果你长时间的需要很多数据数据去存储,你可以通过
getFreeSpace() 或者 **getTotalSpace()**方法去查询可用空间的大小(如果存储空间不够,还在往磁盘中存数据,则抛出IOException),如果你的可用空间的少于90%,那么你就不能再在硬盘上存储数据了。

###删除文件

如果文件不需要了,你应该及时的删除,通常都是文件调用自己的delete() 方法来删除自己。

myFile.delete();

如果文件存储在internal storage,你也可以通过Context中的deleteFile()方法来删除文件。

myContext.deleteFile(fileName);

小结:
如果用户卸载了你的App,系统会删除以下文件:

  1. 你存储在internal storage上的所有文件。
  2. 你通过getExternalFilesDir()获取到external storage中的目录中的所有文件。
    你应该去删除通过getCacheDir()获取到缓存文件和你不再需要的文件。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值