Android存储之——文件存储

悠悠 2022-08-19 15:09 272阅读 0赞

文件存储记好一个方法openFileOutput()

返回值为FileOutputStream对象

两个参数:

参数一:要保存的文件名字

如”FileName.txt”,注意不要写目录,它有默认的目录下,data/data/包名/files/下

参数二:文件的操作模式。

主要有两种模式:Context.MODE_PRIVATE 和 MODE_APPEND,默认为MODE_PRIVATE,同名时会被覆盖;MODE_APPEND同名时会追加。还有两种不安全的模式允许其他程序对其操作,极其不安全,在Android 4.20之后被废弃了。
openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。

创建的文件保存在/data/data/<package name>/files目录,如: /data/data/cn.itcast.action/files/itcast.txt ,通过点击Eclipse菜单“Window”-“Show View”-“Other”,在对话窗口中展开android文件夹,选择下面的File Explorer视图,然后在File Explorer视图中展开/data/data/<package name>/files目录就可以看到该文件。

openFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为:

Context.MODE_PRIVATE = 0

Context.MODE_APPEND = 32768

Context.MODE_WORLD_READABLE = 1

Context.MODE_WORLD_WRITEABLE = 2

Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND

Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。

MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;

MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

如果希望文件被其他应用读和写,可以传入: openFileOutput(“itcast.txt”, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE); android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),其他程序无法访问。

除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。

下面例子是一个存储EditText中输入内容的例子,在EditText按返回键销毁前保存数据,重写onDestory()方法。

xml布局文件中的代码:

  1. <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" >
  2. <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入你要存储的内容" />
  3. </LinearLayout>

MainActivity中代码:

  1. package org.day13_filesave;
  2. import java.io.BufferedWriter;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.OutputStreamWriter;
  6. import android.app.Activity;
  7. import android.content.Context;
  8. import android.os.Bundle;
  9. import android.view.Menu;
  10. import android.widget.EditText;
  11. public class MainActivity extends Activity {
  12. EditText editText;
  13. @Override
  14. protected void onCreate(Bundle savedInstanceState) {
  15. super.onCreate(savedInstanceState);
  16. setContentView(R.layout.activity_main);
  17. editText = (EditText) findViewById(R.id.editText);
  18. }
  19. @Override
  20. protected void onDestroy() {
  21. super.onDestroy();
  22. // 得到输入内容
  23. String data = editText.getText().toString();
  24. save(data, "fileName.txt");
  25. }
  26. public void save(String data, String name) {
  27. FileOutputStream fos = null;
  28. BufferedWriter bw = null;
  29. try {
  30. /** * @return 返回值 为FileOutputStream * @parmas 参数一:指的是要存储的文本的名字,不要写包名 ,有默认的目录 data/data/<package>/files/ * @parmas 参数二:操作模式,一般默认选用Context.MODE_PRIVATE * 出现同名时直接覆盖,还有一种是MODE_APPEND追加 */
  31. fos = openFileOutput(name, Context.MODE_PRIVATE);
  32. // 利用缓冲流写入,中间使用了转换流将字节流转换成字符流
  33. bw = new BufferedWriter(new OutputStreamWriter(fos));
  34. bw.write(data);
  35. bw.flush();
  36. } catch (Exception e) {
  37. // TODO Auto-generated catch block
  38. e.printStackTrace();
  39. } finally {
  40. if (fos != null) {
  41. try {
  42. fos.close();
  43. } catch (IOException e) {
  44. // TODO Auto-generated catch block
  45. e.printStackTrace();
  46. }
  47. }
  48. if (bw != null) {
  49. try {
  50. bw.close();
  51. } catch (IOException e) {
  52. // TODO Auto-generated catch block
  53. e.printStackTrace();
  54. }
  55. }
  56. }
  57. }
  58. }

下面就增加一点难度,实现下次打开时候,输入框直接显示上次输入的内容。类似于QQ空间发表说说时候来电话了 后来接完电话就关机睡觉,第二天打开发表说说还是前一天编辑一半的内容,并不清空。
这中间有一个读取存储数据的过程,引出另外一个方法openFileInput(),返回值是FileInputStream,参数只有一个,是存储的文件名,依旧不要包名,它去默认目录库下找。

xml布局文件代码不变,参考上面;

MainActivity中代码如下:

  1. package org.day13_filesave;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.io.OutputStreamWriter;
  9. import android.app.Activity;
  10. import android.content.Context;
  11. import android.os.Bundle;
  12. import android.text.TextUtils;
  13. import android.widget.EditText;
  14. import android.widget.Toast;
  15. public class MainActivity extends Activity {
  16. private EditText editText;
  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. // 加载布局
  21. setContentView(R.layout.activity_main);
  22. // 初始化控件
  23. initViews();
  24. }
  25. // 在初始化时完成EditText上次输入内容的读取
  26. private void initViews() {
  27. editText = (EditText) findViewById(R.id.editText);
  28. // 读取上次存储的内容
  29. String inputText = load("fileName.txt");
  30. // 调用TextUtils.isEmpty()方法实现两种判断,是否为""和 是否为null。
  31. if (!TextUtils.isEmpty(inputText)) {
  32. editText.setText(inputText);
  33. // 设置光标位置位于读取到的字符串的末尾
  34. editText.setSelection(inputText.length());
  35. Toast.makeText(this, "恢复数据成功!", 0).show();
  36. }
  37. }
  38. @Override
  39. protected void onDestroy() {
  40. super.onDestroy();
  41. // 得到输入内容
  42. String data = editText.getText().toString();
  43. save(data, "fileName.txt");
  44. }
  45. public void save(String data, String fileName) {
  46. FileOutputStream fos = null;
  47. BufferedWriter bw = null;
  48. try {
  49. /** * @return 返回值 为FileOutputStream * @parmas 参数一:指的是要存储的文本的名字,不要写包名 ,有默认的目录 data/data/<package>/files/ * @parmas 参数二:操作模式,一般默认选用Context.MODE_PRIVATE * 出现同名时直接覆盖,还有一种是MODE_APPEND追加 */
  50. fos = openFileOutput(fileName, Context.MODE_PRIVATE);
  51. // 利用缓冲流写入,中间使用了转换流将字节流转换成字符流
  52. bw = new BufferedWriter(new OutputStreamWriter(fos));
  53. bw.write(data);
  54. bw.flush();
  55. } catch (Exception e) {
  56. // TODO Auto-generated catch block
  57. e.printStackTrace();
  58. } finally {
  59. // 此处不必关闭fos,因为bw封装了fos,一旦外层封装流bw关闭了,内部的fos自然就关闭了
  60. if (bw != null) {
  61. try {
  62. bw.close();
  63. } catch (IOException e) {
  64. // TODO Auto-generated catch block
  65. e.printStackTrace();
  66. }
  67. }
  68. }
  69. }
  70. // 读取上次保存的内容
  71. public String load(String fileName) {
  72. FileInputStream fis = null;
  73. BufferedReader br = null;
  74. StringBuilder content = new StringBuilder();// StringBuilder:是线程不安全的,比StringBuffer效率高
  75. try {
  76. /** * @return 返回值为一个FileInputStream对象 * @param 参数为要打开文件名字 * ,不用包名它去默认的路径下面查找 * */
  77. fis = openFileInput(fileName);
  78. br = new BufferedReader(new InputStreamReader(fis));
  79. String line = "";
  80. while ((line = br.readLine()) != null) {
  81. content.append(line);// 拼接到字符串缓冲区
  82. }
  83. // 返回值转换成String 方便setText用
  84. return content.toString();
  85. } catch (Exception e) {
  86. e.printStackTrace();
  87. } finally {
  88. if (br != null) {
  89. try {
  90. br.close();
  91. } catch (IOException e) {
  92. e.printStackTrace();
  93. }
  94. }
  95. }
  96. return null;
  97. }
  98. }

发表评论

表情:
评论列表 (有 0 条评论,272人围观)

还没有评论,来说两句吧...

相关阅读

    相关 android 存储文件

    首先介绍如何存储数据,显然,要将数据从应用中输出到文件中,必须得到一个输出流outPutStream,然后往输出流中写入数据,在这里Android自带了一个得到应用输出流的方法