前言
文件存储是Android中最基本的一种数据存储方式。Android的文件存储与Java的文件存储类似,都是通过I/O流的形式将数据内容原封不动的存储到文档中。因为他比较适合存储一些简单的文本数据或二进制数据,如果你希望使用文件存储的方式来保存一些较为复杂的的文本数据,就需要定义一套自己的格式规范,这样可以方便之后将数据从文件中重新取出来。
Android中的文件存储分为内部存储和外部存储;
内部存储地址:data/data//files/ 目录
外部存储地址:文件存储到一些外部设备上(通常位于storage/根目录下的内外置存储卡内,不同厂商生产的手机路径可能不同)。
内外部目录
在使用文件存储前,我们先简单了解一下内外部目录获取方式,这个对于文件存储非常重要;对于你将文件存储外部位置还是内部依据你所给的路径决定的,而这里的路径获取方式通过系统方法拿到的。
内部存储文件读写
Context类中提供了一个openFileOutput()方法和openFileInput(), 分比用于将数据存储到内部存储位置和从内部存储位置获取数据;存储路径为:data/data/包名/file。文件的存取用到了FileOutputStream和FileInputStream文件流处理,如果对于这两个流处理不是很清楚的,可以移驾《使用FileInputStream读取本地文件》、《Java输出流FileOutputStream使用详解》了解一下。
1、存储方法openFileOutput()介绍
/**
* Open a private file associated with this Context's application package
* for writing. Creates the file if it doesn't already exist.
* <p>
* No additional permissions are required for the calling app to read or
* write the returned file.
*
* @param name The name of the file to open; can not contain path
* separators.
* @param mode Operating mode.
* @return The resulting {@link FileOutputStream}.
* @see #MODE_APPEND
* @see #MODE_PRIVATE
* @see #openFileInput
* @see #fileList
* @see #deleteFile
* @see java.io.FileOutputStream#FileOutputStream(String)
*/
public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
throws FileNotFoundException;
该方法主要有两个参数,第一个参数:
该参数就是创建文件的文件名。注意不能包含”/”斜杠符号,因此这里指定的文件名可以不包含路径。文件会 默认存储到data/data/包名/files目录下。第二个参数:
是文件的操作模式,分别为, MODE_PRIVATE、MODE_APPEND、Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE:
操作模式 | 解释说明 |
Context.MODE_PRIVATE | 为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND |
Context.MODE_APPEND | 模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。 |
Context.MODE_WORLD_READABLE | 表示当前文件可以被其他应用读取; |
Context.MODE_WORLD_WRITEABLE | 表示当前文件可以被其他应用写入。 |
EXP:
method 1:(写入byte数据类型)
String saveInfo = "string";
//用MODE_PRIVAT模式,创建一个test.txt文件
FileOutputStream fileOutput = openFileOutput("test.txt", MODE_PRIVATE);
fileOutput.write(saveInfo.getBytes());//将我们写入的字符串变成字符数组
fileOutput.flush();//刷新流
fileOutput.close();//关闭流
method 2:(写入字符或字符串数据类型)
String saveInfo = "string";
FileOutputStream fileOutput = openFileOutput("test.txt", MODE_PRIVATE);
OutputStreamWriter writerOutput = new OutputStreamWriter(fileOutput);
BufferedWriter writer = new BufferedWriter(writerOutput );
writer.write(saveInfo);
writer.flush();//刷新流
writer.close();//关闭流
2、取方法openFileInput()介绍
/**
* Open a private file associated with this Context's application package
* for reading.
*
* @param name The name of the file to open; can not contain path
* separators.
*
* @return The resulting {@link FileInputStream}.
*
* @see #openFileOutput
* @see #fileList
* @see #deleteFile
* @see java.io.FileInputStream#FileInputStream(String)
*/
public abstract FileInputStream openFileInput(String name)
throws FileNotFoundException;
该方法只有已个参数,参数:
这个方法只有一个参数,就是要打开的文件名,这个文件名也不能包含“/”斜杠符号。
EXP:
method 1:(获取byte数据类型)
String saveInfo = "string";
FileInputStream fileInput = openFileInput("test.txt");
int len = 0;
//每次读取1024个byte的数据
byte[] bytes = new byte[1024];
while ((len = fileInput.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len));
}
fileInput .flush();//刷新流
fileInput .close();//关闭流
method 2:(获取字符或字符串数据类型)
String saveInfo = "string";
FileInputStream fileInput = openFileInput("test.txt", MODE_PRIVATE);
InputStreamReader readInput = new InputStreamReader(fileInput);
BufferedReader read = new BufferedReader(readInput);
String line = "";
StringBuilder result = new StringBuilder();
while ((line = reader.readLine()) != null) {
result.append(line);
}
fileInput.flush();//刷新流
fileInput.close();//关闭流
外部存储文件读写
所有的Android设备都支持保存文件到外部存储,外部存储可能是可移除的存储介质(例如SD卡)或者手机内部介质,保存到外部存储的文件是全局可读取文件,用户可以修改这些文件。使用外部存储几大因数(纯粹个人见解,有不同见解的可以留言探讨及更改):
a、减少内部存储压力;
b、将文件或数据与其他进程共享;
c、应用产生的文件在应用卸载后仍需保留。
注意:外部存储分为公共目录和私有目录,外部存储是可以全局访问的,但需要申请权限:
Android4.4前访问私有目录和公共目录都需要申请 WRITE_EXTERNAL_STORAGE 权限
Android4.4后访问私有目录不需要申请权限,但公共目录是需要申请 WRITE_EXTERNAL_STORAGE 权限
外部文件的读写操作同样也用到了I/O流操作,FileOutputStream和FileInputStream文件流处理,如果对于这两个流处理不是很清楚的,可以移驾《使用FileInputStream读取本地文件》、《Java输出流FileOutputStream使用详解》了解一下。
1、存储方法介绍
这里简单讲述一下FileOutputStream流几种创建方式:
第一种:创建FileOutputStream流以写入数据到指定路径所代表的文件,同时创建一个新的FileDescriptor对象来表示与该文件的关联(源码中会new一个该对象);
public FileOutputStream(File file){}
第二种:创建FileOutputStream流以写入数据到File对象表示的文件。 如果第二个参数为true,则字节将写入文件的末尾而不是开头;如果第二个参数为false,则写入的内容会覆盖原文件的内容。 创建一个新的FileDescriptor对象来表示此文件连接。其抛异常的规则与第一个构造函数一致;
public FileOutputStream(File file,boolean append){}
第三种:创建FileOutputStream流以写入数据到指定路径所代表的文件,同时创建一个新的FileDescriptor对象来表示与该文件的关联(源码中会new一个该对象)
public FileOutputStream(String name){}
第四种:创建FileOutputStream流以写入数据到指定路径所代表的文件,同时创建一个新的FileDescriptor对象来表示与该文件的关联(源码中会new一个该对象), 如果第二个参数为true,则字节将写入文件的末尾而不是开头,同样如果第二个参数为false,则写入的内容会覆盖原文件的内容
public FileOutputStream(String name,boolean append){}
虽然FileOutputStream有四种构造方法,但是究其本质发现都是调用了FileOutputStream(File file,boolean append)这个构造方法,因此后续使用FileOutputStream流时,直接使用该构造方法即可。
EXP:
method 1:(写入byte数据类型)
String saveInfo = "string";
//创建一个test.txt文件,且使用覆盖方式
File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
FileOutputStream fileOutput = new FileOutputStream(fileName, false);
fileOutput.write(saveInfo.getBytes());//将我们写入的字符串变成字符数组
fileOutput.flush();//刷新流
fileOutput.close();//关闭流
method 2:(写入字符或字符串数据类型)
String saveInfo = "string";
File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
FileOutputStream fileOutput = new FileOutputStream(fileName, false);
OutputStreamWriter writerOutput = new OutputStreamWriter(fileOutput);
BufferedWriter writer = new BufferedWriter(writerOutput );
writer.write(saveInfo);
writer.flush();//刷新流
writer.close();//关闭流
2、取方法介绍
这里简单讲述一下FileInputStream流两种种创建方式:
第一种:通过打开与File类对象代表的实际文件的链接来创建FileInputStream流对象;
public FileInputStream(File file){}
第二种:通过指定的字符串参数来创建File类对象,而后再与File对象所代表的实际路径建立链接创建FileInputStream流对象
public FileInputStream(String name){}
虽然FileOutputStream有四种构造方法,但是究其本质发现都是调用了FileOutputStream(File file,boolean append)这个构造方法,因此后续使用FileOutputStream流时,直接使用该构造方法即可。
EXP:
method 1:(获取byte数据类型)
String saveInfo = "string";
File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
FileInputStream fileInput = new FileInputStream(fileName);
int len = 0;
//每次读取1024个byte的数据
byte[] bytes = new byte[1024];
while ((len = fileInput.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len));
}
fileInput .flush();//刷新流
fileInput .close();//关闭流
method 2:(获取字符或字符串数据类型)
String saveInfo = "string";
File fileName = new File(Environment.getExternalStoragePublicDirectory(directory), "test.txt");
FileInputStream fileInput = new FileInputStream(fileName);
InputStreamReader readInput = new InputStreamReader(fileInput);
BufferedReader read = new BufferedReader(readInput);
String line = "";
StringBuilder result = new StringBuilder();
while ((line = reader.readLine()) != null) {
result.append(line);
}
fileInput.flush();//刷新流
fileInput.close();//关闭流
备注
其实不管是内部还是外部存储,存储的流程方式基本一致,唯一不一样的是对于I/O流FileInputStream和FileOutputStream对象的创建方式不一样。这里补充一句,如果对于文件的权限要求不是很高,建议尽量将文件数据存储在外部存储设备中。