适用类型:流式顺序数据的读写

Android中使用的文件 File,其实就是一个基于磁盘的文件系统,早期的设备将数据存储分成了两个部分:设备中内存大小固定不可变的内部存储和类似于SD Card的外部存储。在后面我所接触的设备中将这两个部分集成在了一起,做成了不可卸载的内置存储,但在逻辑上还是分成了内部存储和外部存储。

内置存储(internal):在设备中始终是可用的;数据只提供给我们的APP访问;APP被卸载时,保存的数据同时被删除

外部存储(external):当用户通过USB存储模式挂载外部存储器,取下挂载的这部分后,就无法对其进行访问;用户或者其他的APP可以访问外部存储的数据;当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件

tip:APP默认是安装在内置存储中的,通过配置文件 AndroidManifest.xm 中的标签 manifest 中的属性 android:installLocation 可设置APP的安装位置

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.oschina.git.zhaikun.androiddeveloped"
android:installLocation="preferExternal">

1、外部存储(external)使用权限声明

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

tip:如果我们申明了写的权限,那么默认就有了读的权限;如果我们的程序只需要读的权限,那么需要声明对外部存储的读权限

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

2、内置存储的访问

由于我们安装的程序默认就可以对程序目录下的文件进行读写操作,所以不需要声明对内置存储文件的访问权限

3、操作external storage

在对外部存储文件进行读写操作时,由于外部存储可能存在不可用的状态(比如sd card被拔出),因此一个良好的习惯就是在进行读写之前先对external storage的状态进行判断

package net.oschina.git.zhaikun.androiddeveloped.utils;

import android.os.Environment;

/**
* Created by zhaikun68 on 2017/7/28.
* <p>
* 检查external storage的挂载状态
*/
public class CheckExternalStorageState {

/**
* 判断是否可以对external storage进行读写
*
* @return true/false
*/
public boolean isExternalStorageWriteableAndReadable() {
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
return true;
}
return false;
}

/**
* 对external storage仅需要读的权限时,判断是否可以进行读的操作
*
* @return true/false
*/
public boolean isExternalStorageReadable() {
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(Environment.getExternalStorageState())) {
return true;
}
return false;
}
}

在申明一个文件时,对文件的类型进行定义

public file:访问权限为public的文件,在APP卸载后,仍可保证之前所创建的文件依然可以保存在external storage中提供给用户及其他APP所访问

private file:访问权限为private的文件,从原理上来说,保存在external storage中的文件都是可以被用户和其他APP所访问的,但当文件类型声明为private时,说明文件中保存的数据对其他APP没有任何实际上的意义,在APP被卸载时,会同时删除在APP中声明的类型为private的保存在external storage中的文件

获取或定义一个public file

//getExternalStoragePublicDirectory()方法中需传入一个type,实为文件中保存数据的类型,比如音乐文件DIRECTORY_MUSIC或图片文件DIRECTORY_PICTURES等
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "file_name");
if (file.mkdirs())//创建此抽象路径名指定的目录,包括所有必需但不存在的父目录
value.setText("文件创建成功");
else {
value.setText("文件创建失败");
}

tip:mkdirs()方法在创建文件时,会自检所需创建的文件是否存在,文件存在时不会进行二次创建

获取或定义一个private file

File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),"private_file");
if (file.mkdirs()) {
value.setText("文件创建成功");
}else{
value.setText("文件创建失败");
}

4、操作internal storage

//getFilesDir()创建文件,代表了APP的internal目录
File file = new File(getFilesDir(), "internal_file");

使用getCacheDir()方法可以创建一个带有缓存的文件,在系统内存空间不足时,会自动删除internal storage中的缓存文件,该文件保存在internal的缓存目录下,以APP的包名作为指定标识:data/data/包名/文件名