文件存储
文件存储
文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据。如果你想使用文件存储的方式来保存一些较为复杂的文本数据,就需要定义一套自己的格式规范,这样方便于之后将数据从文件中重新解析出来
如何在 Android 项目中使用文件存储的技术
1 新建一个 FilePersistenceTest 项目
2 修改MainActivity 中的代码, 并修改布局activity_main.xml .
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.EditText;
public class MainActivity extends Activity {
private EditText edit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
}
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();
// (文件内容,文件名称)
saveFileTxt(inputText, "data");
}
/**
* 保存数据到文件 默认存储到/data/data/<packagename>/files/目录下
*
* @param @param requestData 要保存的字符串
* @param @param filename 文件名称
* @return void
* @throws
*/
public void saveFileTxt(String requestData, String filename) {
FileOutputStream out = null;
BufferedWriter writer = null;
try {
// MODE_PRIVATE 默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容
// MODE_APPEND 则表示如果该文件已存在就往文件里面追加内容,不存在就创建新文件。
out = openFileOutput(filename, Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(requestData);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
布局文件 activity_main.xml .
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type something here" />
</LinearLayout>
3 运行程序了,输入内容,再按下 Back 键后, 程序退出.
解析:
Context 类中提供了一个 openFileOutput ()方法,可以用于将数据存储到指定的文件中。 openFileOutput ()方法返回的是一个 FileOutputStream 对象,得到了这个对象之后就可以使用 Java 流的方式将数据写入到文件中了。
可以看到, 首先我们在 onCreate()方法中获取了 EditText 的实例, 然后重写了 onDestroy()方法,这样就可以保证在活动销毁之前一定会调用这个方法。在 onDestroy()方法中我们获取了 EditText 中输入的内容,并调用 saveTxt()方法把输入的内容存储到文件中,文件命名为 data.
然后按下 Back 键关闭程序,这时我们输入的内容就已经保存到文件中了。那么如何才能证实数据确实已经保存成功了呢?我们可以借助 DDMS 的 File Explorer 来查看一下。 切换到 DDMS 视 图 , 并 点 击 File Explorer 切 换 卡 , 在 这 里 进 入 到 /data/data/<packagename>/files/
目录下,可以看到生成了一个 data 文件
将这个文件导出到电脑上。使用记事本打开这个文件,里面的内容就是你输入的数据.
这样就证实了,在 EditText 中输入的内容确实已经成功保存到文件中了。
不过只是成功将数据保存下来还不够,我们还需要想办法在下次启动程序的时候让这些数据能够还原到 EditText 中,因此接下来我们就要学习一下,如何从文件中读取数据。
从文件中读取数据
修改 MainActivity中的代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText edit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
String inputText = readFileTxt("data");
if (!TextUtils.isEmpty(inputText)) {
edit.setText(inputText);
edit.setSelection(inputText.length());
Toast.makeText(this, "读取成功", 0).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();
// (文件内容,文件名称)
saveFileTxt(inputText, "data");
}
/**
* 保存数据到文件 默认存储到/data/data/<packagename>/files/目录下
*
* @param @param requestData 要保存的字符串
* @param @param filename 文件名称
* @return void
* @throws
*/
public void saveFileTxt(String requestData, String filename) {
FileOutputStream out = null;
BufferedWriter writer = null;
try {
// MODE_PRIVATE 默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容
// MODE_APPEND 则表示如果该文件已存在就往文件里面追加内容,不存在就创建新文件。
out = openFileOutput(filename, Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(requestData);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 从文件中读取数据
*
* @param @param filename 文件名称
* @return String 返回 String
* @throws
*/
public String readFileTxt(String filename) {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput(filename);
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
}
2 运行程序,查看效果
解析:
Context 类中还提供了一个 openFileInput()方法,用于从文件中读取数据。
首先通过 openFileInput()方法获取到了一个 FileInputStream 对象,然后借助它又构建出了一个 InputStreamReader 对象,接着再使用 InputStreamReader 构建出一个 BufferedReader 对象,这样我们就可以通过 BufferedReader 进行一行行地读取,把文件中所有的文本内容全部读取出来并存放在一个 StringBuilder 对象中,最后将读取到的内容返回就可以了。
这里的思路非常简单,在 onCreate()方法中调用 load()方法来读取文件中存储的文本内容,如果读到的内容不为空, 就调用 EditText 的 setText()方法将内容填充到 EditText里,并调用 setSelection 方法将输入光标移动到文本的末尾位置以便于继续输入,然后弹出一句还原成功的提示。
注意在代码中对字符串进行非空判断的时候使用了 TextUtils.isEmpty()方法,这是一个非常好用的方法,它可以一次性进行两种空值的判断。当传入的字符串等于 null 或者等于空字符串的时候,这个方法都会返回 true,从而使得我们不需要单独去判断这两种空值,再使用逻辑运算符连接起来了。
这样我们就已经把文件存储方面的知识学习完了,其实所用到的核心技术就是 Context类中提供的 openFileInput()和 openFileOutput()方法,之后就是利用 Java 的各种流来进行读写操作就可以了
另外:
上面的文件存储,是将文件保存到系统文件中,用户是看不到的,甚至一些程序员都不定知道如何查看, 那么有没有方法将数据保存到内存卡或者本地根目录中呢?
新建一个工具类
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import android.os.Environment;
/**
* 类名称:FileUtil</br>
* 类描述:文件工具类</br>
*/
public class FileUtil {
/**
* 配合测试把json数据写入文件中(因为数据太大,无法打印全部数据)
*
* @param requestData
* @param filePath
*/
public static void writeTxt(String requestData, String filePath) {
String json = requestData + "\n";
File file = new File(filePath); // 要写入的文件
BufferedWriter writer = null;
try {
if (!file.exists()) {
file.createNewFile();
}
writer = new BufferedWriter(new FileWriter(file, true));
writer.newLine();
writer.write(json);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 将File文件读成String
*
* @param @param filepath 文件路径,如:/sdcard/test.txt
* @return String 返回类型
* @throws
*/
public static String file2String(String filepath) {
String str = "";
try {
String encoding = "UTF-8";
File urlFile = new File(filepath);
if (urlFile.isFile() && urlFile.exists()) { // 判断文件是否存在
InputStreamReader isr =
new InputStreamReader(new FileInputStream(urlFile), encoding);
BufferedReader br = new BufferedReader(isr);
String mimeTypeLine = null;
while ((mimeTypeLine = br.readLine()) != null) {
str = str + mimeTypeLine;
}
} else {
System.out.println("找不到指定的文件");
}
} catch (Exception e) {
System.out.println("读取文件内容出错");
e.printStackTrace();
}
return str;
}
/**
* 获取sd卡路径
*
* @return
*/
public static String getSDPath() {
File sdDir = null;
// 判断sd卡是否存在
boolean sdCardExist = Environment.getExternalStorageState()
.equals(android.os.Environment.MEDIA_MOUNTED);
if (sdCardExist) // 如果SD卡存在,则获取跟目录
{
sdDir = Environment.getExternalStorageDirectory();// 获取跟目录
}
return sdDir.toString();
}
}
添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
在MainActivity中调用工具类方法,读写文件.
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.Toast;
import com.yassblog.utils.FileUtil;
public class MainActivity extends Activity {
private EditText edit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
// 读取数据
String inputText = FileUtil.file2String(FileUtil.getSDPath()+"/ceshi1.txt");
if (!TextUtils.isEmpty(inputText)) {
edit.setText(inputText);
edit.setSelection(inputText.length());
Toast.makeText(this, "读取成功", 0).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();
// 保存数据 (文件内容,文件路径)
FileUtil.writeTxt(inputText, FileUtil.getSDPath()+"/ceshi1.txt");
}
}