详解Android开发数据持久化之文件存储(附源码)
其实我们在社交网络上面所发出的任何信息, 都希望能够保留下来. 那么如何实现呢?
数据持久化
数据持久化, 就是将内存中的瞬时数据保存在存储设备中, 保证即便关机之后, 数据仍然存在.
保存在内存中的数据是瞬时数据, 保存在存储设备中的数据就是处于持久状态的.
持久化技术则是提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换, Android系统中主要提供了3种方式用于简单地实现数据持久化功能, 即文件存储, SharePreference存储, 以及数据库存储. 当然你也可以将数据保存在手机的SD卡中.
文件存储
文件存储是android中最基本的一种数据存储方式, 它不对存储的内容进行任何的格式化处理, 所有的数据都是原封不动地保存到文件当中, 因为他比较适合存储一些简单的文本数据或二进制数据. 如果你希望使用文件存储的方式来保存一些较为复杂的的文本数据, 就需要定义一套自己的格式规范, 这样可以方便之后将数据从文件中重新取出来.
将数据存储在文件中
Context类中提供了一个openFileOutput()方法, 可以用于将数据存储在指定的文件中. 这个方法接收两个参数,
第一个参数是文件名, 在文件创建的时候使用的就是这个名称, 注意这里指定的文件名不可以包含路径的. 因为所有的文件都是默认存储到/data/data/<package name>/files/目录下.
第二个参数是文件的操作模式, 主要有两种模式可以选, MODE_PRIVATE和MODE_APPEND. 其中MODE_PRIVATE是默认的操作模式, 表示当指定同样文件名的时候, 所写入的内容将会覆盖原文件中的内容. 而MODE_APPEND则表示如果该文件已存在, 就往文件里面追加内容, 不存在就创建新文件.
openFileOutput()方法返回的是一个FileOutputStream对象, 得到了这个对象之后就可以使用java流的方式将数据写入到文件中了.
public void save(){ String data = "Data to save"; FileOutputStream out = null; BufferedWriter writer = null; try { out = openFileOutput("data", Context.MODE_PRIVATE); writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write(data); }catch (IOException e) { e.printStackTrace(); } finally { try { if(writer!= null){ writer.close(); } } catch (IOException e) { e.printStackTrace(); } } }
说明: 通过openFileOutput()方法能够得到一个FileOutputStream对象, 然后再借助它构建出一个OutputStreamWriter对象, 接着再使用OutputStreamWriter构建出一个BufferedWriter对象, 这样就可以通过BufferedWriter来讲文本内容写入到文件中了.
下面我们来一个完整的例子来理解一下,当我们在退出程序之前, 将我们在文本框中输入的内容储存在文件中.
新建项目FilePersistenceDemo项目, 且修改activity_main.xml中的代码.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
说明: 界面只有一个EditText文本框.
MainActivity.java文件:
public class MainActivity extends AppCompatActivity { private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取editText实例 editText = (EditText)findViewById(R.id.edit); } // 重写onDestroy(), 可以保证活动销毁之前一定会调用这个方法. @Override protected void onDestroy() { super.onDestroy(); String inputText = editText.getText().toString(); save(inputText); } public void save (String inputText){ FileOutputStream out = null; BufferedWriter writer = null; try { out = openFileOutput("data", Context.MODE_PRIVATE); writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write(inputText); } catch (IOException e) { e.printStackTrace(); } finally { try { if(writer!= null) { writer.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
那么我们运行程序, 我们输入的内容就会保存在文件中. 如果您的手机已经Root了, 可以直接在 应用程序的包名/files目录就可以发现.
从文件中读取数据
核心代码:
public String load (){ FileInputStream in = null; BufferedReader reader = null; StringBuilder content = new StringBuilder(); try { //获取FileInputStream对象 in = openFileInput("data"); //借助FileInputStream对象, 构建出一个BufferedReader对象 reader = new BufferedReader(new InputStreamReader(in)); String line = ""; //通过BufferedReader对象进行一行行的读取, 把文件中的所有内容全部读取出来 // 并存放在StringBuilder对象中 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(); }
修改我们MainActivity中的代码:
public class MainActivity extends AppCompatActivity { private EditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取editText实例 editText = (EditText)findViewById(R.id.edit); String inputText = load(); //TextUtils.isEmpty()可以一次性判断两种非空判断 传入null或者空, 都返回true if(!TextUtils.isEmpty((inputText))){ editText.setText(inputText); //setSelection()表示将光标移动在文本框的末尾位置, 以便继续输入 editText.setSelection(inputText.length()); //弹出Toast, 给出一个提示, 表示读取数据成功 Toast.makeText(this, "读取数据成功!", Toast.LENGTH_SHORT).show(); } } // 重写onDestroy(), 可以保证活动销毁之前一定会调用这个方法. @Override protected void onDestroy() { super.onDestroy(); String inputText = editText.getText().toString(); save(inputText); } public void save (String inputText){ FileOutputStream out = null; BufferedWriter writer = null; try { out = openFileOutput("data", Context.MODE_PRIVATE); writer = new BufferedWriter(new OutputStreamWriter(out)); writer.write(inputText); } catch (IOException e) { e.printStackTrace(); } finally { try { if(writer!= null) { writer.close(); } } catch (IOException e) { e.printStackTrace(); } } } public String load (){ FileInputStream in = null; BufferedReader reader = null; StringBuilder content = new StringBuilder(); try { //获取FileInputStream对象 in = openFileInput("data"); //借助FileInputStream对象, 构建出一个BufferedReader对象 reader = new BufferedReader(new InputStreamReader(in)); String line = ""; //通过BufferedReader对象进行一行行的读取, 把文件中的所有内容全部读取出来 // 并存放在StringBuilder对象中 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(); } }
效果演示