最近利用下班时间,找了看什么书比较适合初学android的朋友,很多人推荐了这本书,于是就买了一本,感觉看书,思考,动手,再思考和总结这样过程还是很有必要的,于是就打算把自己学习的东西简单的总结一下;方便自己以后查找,也有利于学习的巩固。在这里首先要感谢一下书籍的作者——郭霖前辈。
本篇开始与接下来的三篇以及一个附篇都会介绍一下Android系统中数据持久化的基本内容,本章主要介绍通过本地文件的方式来存储数据。由于把数据存储在SD卡中相对比较繁琐和危险,所以我会放在附篇中介绍。这里介绍的通过本地文件存储数据应该说是Android中的一种最基本的方式了。它对要存储的数据不做任何处理;所以常常用于存储一些比较简单的文本数据;对于一些复杂的数据;考虑后期取出的时候解析过于麻烦,通常不采用这种方式。
1,基本概念与要点
- Context类中提供一个openFileOutput()方法,用于存储数据到指定文件;它接受两个参数,第一个文件名称,第二个保存的方式;默认的保存路径为data/data/<packagename>/files目录下
- Context类中提供一个openFileInput()方法,用于读取指定文件数据;它接受一个参数,就是文件名称
对于这两个方法,返回的都是一个流对象,前者是输出流,后者是一个输入流;指向上面已经说了。所以这种方式保存数据是非常简单的;下面就来看看具体的使用吧。
2,代码示例
AppFileActivity.java代码:
package com.hfut.operationappfile;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class AppFileActivity extends AppCompatActivity {
EditText editFileName;
EditText fileContent;
TextView readFileContent;
Button saveButton;
Button readButton;
Button editButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_file);
initUI();
}
private void initUI() {
editFileName = findViewById(R.id.editFileName);
fileContent = findViewById(R.id.editFileContent);
readFileContent = findViewById(R.id.readFileContent);
saveButton = findViewById(R.id.saveFile);
editButton = findViewById(R.id.editFile);
readButton = findViewById(R.id.readFile);
}
// @Override
// public void onClick(View v) {
// switch (v.getId()) {
// case R.id.saveFile:
// saveFile();
// break;
// case R.id.readFile:
// readFile();
// break;
// case R.id.editFile:
// editFile();
// break;
// default:
// break;
//
// }
// }
public void save(View view) {
saveFile();
fileContent.setText("");
editFileName.setText("");
fileContent.setHint("请输入要保存数据");
editFileName.setHint("请输入文件名称");
}
public void read(View view) {
readFile();
}
public void edit(View view) {
editFile();
}
/**
* 下面保存文件数据和读取文件数据其实包的异常都是一样的,这里我给了不同的处理
* 在编辑文件的时候,我自己用IOException涵盖了FileNotFoundException
* 在读取文件的时候,我保留了原样
* 还有一个编辑上一次保存的文件数据,加了一个光标定位;
*/
//编辑数据
private void saveFile() {
String fileName = editFileName.getText().toString();
if (TextUtils.isEmpty(fileName)) {
readFileContent.setText("请您先输入要查看的文件名称");
} else {
String tempfileContent = fileContent.getText().toString();
BufferedWriter writer = null;
//以MODE_PRIVATE形式,还可以以MODE_APPEND,自己可以试一试
try {
OutputStream out = openFileOutput(fileName, MODE_PRIVATE);
// OutputStream out=openFileOutput(fileName,MODE_APPEND);
//对输出流两次包装;字节流--字符流--字符缓冲流
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(tempfileContent);
readFileContent.setText(editFileName.getText().toString()+"保存成功,可以点击读取文件查看");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//读取数据
private void readFile() {
String fileName = editFileName.getText().toString();
if (TextUtils.isEmpty(fileName)) {
readFileContent.setText("请您先输入要查看的文件名称");
} else {
StringBuilder stringBuilder = new StringBuilder();
try {
InputStream in = openFileInput(fileName);
//两次包装,同上
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String readLineContent = "";
try {
while ((readLineContent = reader.readLine()) != null) {
stringBuilder.append(readLineContent);
}
readFileContent.setText(fileName + "中的数据是:\n");
readFileContent.append(stringBuilder.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (FileNotFoundException e) {
readFileContent.setText("对不起,您输入的文件不存在,请重新输入");
e.printStackTrace();
}
}
}
//编辑上次保存或者编辑的数据
private void editFile() {
readFileContent.setText("你现在可以对文件数据进行修改编辑了,别忘了修改之后记得保存哟!");
String fileName = editFileName.getText().toString();
StringBuilder stringBuilder = new StringBuilder();
try {
InputStream in = openFileInput(fileName);
//两次包装,同上
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String readLineContent = "";
try {
while ((readLineContent = reader.readLine()) != null) {
stringBuilder.append(readLineContent);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (FileNotFoundException e) {
readFileContent.setText("对不起,您输入的文件不存在,请重新输入");
e.printStackTrace();
}
fileContent.setText(stringBuilder.toString());
if (!TextUtils.isEmpty(stringBuilder.toString())) {
fileContent.setSelection(stringBuilder.toString().length());
}
}
}
activity_app_file.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.hfut.operationappfile.AppFileActivity">
<EditText
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editFileName"
android:hint="请输入文件名称"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editFileContent"
android:hint="请输入要保存数据"/>
<LinearLayout
android:layout_marginTop="20dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:onClick="save"
android:id="@+id/saveFile"
android:text="保存文件"
android:layout_marginTop="10dp"
android:layout_marginLeft="150dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:onClick="read"
android:id="@+id/readFile"
android:text="读取文件"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:onClick="edit"
android:id="@+id/editFile"
android:text="编辑文件"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:layout_marginTop="20dp"
android:textSize="15dp"
android:id="@+id/readFileContent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="显示读取文件的数据"
/>
</LinearLayout>
主配置文件AndroidManifest.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hfut.operationappfile">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".AppFileActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
3,运行结果
第一步:运行程序
图 1
第二步:不输入任何数据,点击任意一个按钮
图 2
第三步:输入一个文件名称,并输入在该文件中要保存的数据
图 3
第四步:点击保存
图 4
第五步:输入刚刚保存的文件名称,点击“读取文件”按钮
图 5
第六步:再点击“编辑文件”按钮
图 6
第七步:重新编辑上次存储的文本内容,然后点击“保存文件”按钮
图 7
第八步:点击“读取文件”按钮
图 8
第九步:输入一个其他的文件名称,并点击“读取文件”或者“编辑文件”按钮
图 9
第十步:打开/data/data/下的app应用包,会发现多了一个files文件夹,并且里面有一个why.txt文件,内容如下图:
图 10
总结:这部分总得来说还是很简单的,也没有需要特别说明的地方,在openFileOutput()的第二个参数中,我们这里使用的是
MODE_PRIVATE,你也可以试试另一个MODE_APPEND;我在代码中也都写了,只要取消注释就可以,这个append和StringBuffer和StringBiulder中的append()方法含义一样,就是在文件后面追加这些数据;而不是像第一个覆盖原有数据。好了,这一部分到这里就说完了。再见了