数据存储之文件存储
保存在内存中的数据是处于瞬间状态的,而保存在存储设备上的数据是持久的,一直存在,除非被删除。从该篇开始总结Android中的几种数据存储方式:
- 文件存储
- SharedPreferences
- 数据库SQLite
- ContentProvider
文件存储概述
常用的文件的操作模式
MODE_PRIVATE: 默认的操作,表示当指定同样的文件名时,所写入的内容会覆盖原文件内容。
MODE_APPEND 表示如果该文件已存在就往里面追加内容,不再重新创建新文件。
另外Context类中还有MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE、MODE_MULTI_PROCESS、MODE_ENABLE_WRITE_AHEAD_LOGGING、MODE_NO_LOCALIZED_COLLATORS等操作模式,其中MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE在Android4.2版本已被舍弃。
Context类中几个重要的方法:
- getDir(String name , int mode):在应用程序的数据文件夹下获取name对应的子目录,如果没有就创建出来
- getFilesDir():获取该应用程序的数据文件夹得绝对路径/data/data/包名/files
- getCacheDir():获取该应用的cache缓存路径/data/data/包名/cache
- deleteFile(String name)删除应用包内文件名与name对应的文件
- fileList():返回该应用数据文件夹的全部文件
使用Context类提供的openFileOutput()方法将数据存储到指定的文件中
/*
* Context类中的定义的openFileOutput()方法
* @param name The name of the file to open; can not contain path separators.
* @param mode Operating mode. Use 0 or {MODE_PRIVATE} for the default operation. Use {MODE_APPEND} to append to an existing file.
*/
public abstract FileOutputStream openFileOutput(String name, int mode)
throws FileNotFoundException
使用Context类提供的openFileInput()方法从指定的文件中读取数据
/**
* Context类中的定义的openFileInput()方法
* @param name The name of the file to open; can not contain path separators.
*/
public abstract FileInputStream openFileInput(String name)
throws FileNotFoundException;
删除文本文件
/**
* Delete the given private file associated with this Context'sapplication package.
*
* @param name The name of the file to delete; can not contain path separators.
*
* @return {true} if the file was successfully deleted; else {false}.
*/
public abstract boolean deleteFile(String name);
代码调用实例
将数据流写入文本
private final String textfilename = "data"
try {
FileOutputStream fos = openFileOutput(textfilename, MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//或者这样使用BufferedWriter对象写入数据
FileOutputStream out = null;
BufferedWriter writer = null;
try {
out = openFileOutput("data", MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
使用adb命令查看文本内容
//文件默认存储位置:/data/data/包名/files/文件名
root@android:/data/data/com.example.datastore # cd files
cd files
root@android:/data/data/com.example.datastore/files # ls
ls
data.txt
root@android:/data/data/com.example.datastore/files # cat data.txt
cat data.txt
textdata
从文本中读取数据
private String getDataFromText() {
StringBuilder sb = new StringBuilder();
try {
//只接收一个参数(文件名),系统自动到/data/data/包名/files/目录下加载这个文件
FileInputStream fis = openFileInput(textfilename);
int len = 0;
byte[] buf = new byte[1024];
while ((len = fis.read(buf)) != -1) {
sb.append(new String(buf, 0, len));
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
//另一种写法
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (reader!=null){
try {
reader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
return content.toString();
在SD卡上读写文件
1.在SD卡上读写文件需要具备下面权限:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2.调用Environment类中的getExternalStorageState()方法判断手机上是否存在sd卡,且应用程序具有读写SD卡的权限
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
3.调用Environment.getExternalStorageDirectory()方法来获取外部存储器(SD卡目录)或者使用”/mnt/sdcard/”目录。(模拟器可通过mksdcard命令来创建虚拟存储卡)
4.使用IO流操作SD卡上的文件
//在SD卡上写入数据
private void saveData(String arg) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) { // sd卡存在
File file = new File(Environment.getExternalStorageDirectory()
.toString()
+ File.separator
+ DIR
+ File.separator
+ FILENAME); // 定义File类对象
if (!file.getParentFile().exists()) { // 父文件夹不存在
file.getParentFile().mkdirs(); // 创建文件夹
}
PrintStream out = null; // 打印流对象用于输出
try {
out = new PrintStream(new FileOutputStream(file, true)); // 追加文件
out.println(arg);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close(); // 关闭打印流
}
}
} else { // SD卡不存在
Toast.makeText(this, "保存失败,请插入SD卡!", Toast.LENGTH_LONG).show();
}
}
//从SD卡上读取数据
private String getDataFromSdCard() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) { // SD卡存在
File file = new File(Environment.getExternalStorageDirectory()
.toString()
+ File.separator
+ DIR
+ File.separator
+ FILENAME); // 定义File类对象
if (!file.getParentFile().exists()) { // 父文件夹不存在
file.getParentFile().mkdirs(); // 创建文件夹
}
Scanner scan = null; // 扫描输入
StringBuilder sb = new StringBuilder();
try {
scan = new Scanner(new FileInputStream(file)); // 实例化Scanner
while (scan.hasNext()) { // 循环读取
sb.append(scan.next() + "\n"); // 设置文本
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (scan != null) {
scan.close(); // 关闭打印流
}
}
} else { // SDCard不存在,使用Toast提示用户
Toast.makeText(this, "读取失败,SD卡不存在!", Toast.LENGTH_LONG).show();
}
return null;
}