博客
关于我
Android存储之——文件存储
阅读量:94 次
发布时间:2019-02-26

本文共 7229 字,大约阅读时间需要 24 分钟。

文件存储记好一个方法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布局文件中的代码:

MainActivity中代码:

package org.day13_filesave;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.view.Menu;import android.widget.EditText;public class MainActivity extends Activity {       EditText editText;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        editText = (EditText) findViewById(R.id.editText);    }    @Override    protected void onDestroy() {        super.onDestroy();        // 得到输入内容        String data = editText.getText().toString();        save(data, "fileName.txt");    }    public void save(String data, String name) {        FileOutputStream fos = null;        BufferedWriter bw = null;        try {            /**             * @return 返回值 为FileOutputStream             * @parmas 参数一:指的是要存储的文本的名字,不要写包名 ,有默认的目录 data/data/
/files/ * @parmas 参数二:操作模式,一般默认选用Context.MODE_PRIVATE * 出现同名时直接覆盖,还有一种是MODE_APPEND追加 */ fos = openFileOutput(name, Context.MODE_PRIVATE); // 利用缓冲流写入,中间使用了转换流将字节流转换成字符流 bw = new BufferedWriter(new OutputStreamWriter(fos)); bw.write(data); bw.flush(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (bw != null) { try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }}

下面就增加一点难度,实现下次打开时候,输入框直接显示上次输入的内容。类似于QQ空间发表说说时候来电话了 后来接完电话就关机睡觉,第二天打开发表说说还是前一天编辑一半的内容,并不清空。

这中间有一个读取存储数据的过程,引出另外一个方法openFileInput(),返回值是FileInputStream,参数只有一个,是存储的文件名,依旧不要包名,它去默认目录库下找。

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

MainActivity中代码如下:

package org.day13_filesave;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 editText;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 加载布局        setContentView(R.layout.activity_main);        // 初始化控件        initViews();    }    // 在初始化时完成EditText上次输入内容的读取    private void initViews() {        editText = (EditText) findViewById(R.id.editText);        // 读取上次存储的内容        String inputText = load("fileName.txt");        // 调用TextUtils.isEmpty()方法实现两种判断,是否为""和 是否为null。        if (!TextUtils.isEmpty(inputText)) {            editText.setText(inputText);            // 设置光标位置位于读取到的字符串的末尾            editText.setSelection(inputText.length());            Toast.makeText(this, "恢复数据成功!", 0).show();        }    }    @Override    protected void onDestroy() {        super.onDestroy();        // 得到输入内容        String data = editText.getText().toString();        save(data, "fileName.txt");    }    public void save(String data, String fileName) {        FileOutputStream fos = null;        BufferedWriter bw = null;        try {            /**             * @return 返回值 为FileOutputStream             * @parmas 参数一:指的是要存储的文本的名字,不要写包名 ,有默认的目录 data/data/
/files/ * @parmas 参数二:操作模式,一般默认选用Context.MODE_PRIVATE * 出现同名时直接覆盖,还有一种是MODE_APPEND追加 */ fos = openFileOutput(fileName, Context.MODE_PRIVATE); // 利用缓冲流写入,中间使用了转换流将字节流转换成字符流 bw = new BufferedWriter(new OutputStreamWriter(fos)); bw.write(data); bw.flush(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // 此处不必关闭fos,因为bw封装了fos,一旦外层封装流bw关闭了,内部的fos自然就关闭了 if (bw != null) { try { bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } // 读取上次保存的内容 public String load(String fileName) { FileInputStream fis = null; BufferedReader br = null; StringBuilder content = new StringBuilder();// StringBuilder:是线程不安全的,比StringBuffer效率高 try { /** * @return 返回值为一个FileInputStream对象 * @param 参数为要打开文件名字 * ,不用包名它去默认的路径下面查找 * */ fis = openFileInput(fileName); br = new BufferedReader(new InputStreamReader(fis)); String line = ""; while ((line = br.readLine()) != null) { content.append(line);// 拼接到字符串缓冲区 } // 返回值转换成String 方便setText用 return content.toString(); } catch (Exception e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }}

转载地址:http://nrvk.baihongyu.com/

你可能感兴趣的文章
mysql:Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘解决方法
查看>>
MYSQL:基础——3N范式的表结构设计
查看>>
MYSQL:基础——触发器
查看>>
Mysql:连接报错“closing inbound before receiving peer‘s close_notify”
查看>>
mysqlbinlog报错unknown variable ‘default-character-set=utf8mb4‘
查看>>
mysqldump 参数--lock-tables浅析
查看>>
mysqldump 导出中文乱码
查看>>
mysqldump 导出数据库中每张表的前n条
查看>>
mysqldump: Got error: 1044: Access denied for user ‘xx’@’xx’ to database ‘xx’ when using LOCK TABLES
查看>>
Mysqldump参数大全(参数来源于mysql5.5.19源码)
查看>>
mysqldump备份时忽略某些表
查看>>
mysqldump实现数据备份及灾难恢复
查看>>
mysqldump数据库备份无法进行操作只能查询 --single-transaction
查看>>
mysqldump的一些用法
查看>>
mysqli
查看>>
MySQLIntegrityConstraintViolationException异常处理
查看>>
mysqlreport分析工具详解
查看>>
MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
查看>>
Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
查看>>
mysql_real_connect 参数注意
查看>>