一、首先给大家介绍使用文件如何对数据进行存储,Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。
public class FileActivity extends Activity {
@Override public void onCreate(Bundle savedInstanceState) {
...
FileOutputStream outStream = this.openFileOutput("itcast.txt", Context.MODE_PRIVATE);
outStream.write("传智播客".getBytes());
outStream.close();
}
}
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 ,只有这样其他程序才能正确访问。
三。读取文件的内容
如果要打开存放在/data/data/<package name>/files目录应用私有的文件,可以使用Activity提供openFileInput()方法。
FileInputStream inStream = this.getContext().openFileInput("itcast.txt");
Log.i("FileTest", readInStream(inStream));
readInStream()的方法请看本页下面备注。
或者直接使用文件的绝对路径:
File file = new File("/data/data/cn.itcast.action/files/itcast.txt");
FileInputStream inStream = new FileInputStream(file);
Log.i("FileTest", readInStream(inStream));
注意:上面文件路径中的“cn.itcast.action”为应用所在包,当你在编写代码时应替换为你自己应用使用的包。
对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。
Activity还提供了getCacheDir()和getFilesDir()方法:
getCacheDir()方法用于获取/data/data/<package name>/cache目录
getFilesDir()方法用于获取/data/data/<package name>/files目录
代码示例
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" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/text_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text_name" /> <EditText android:id="@+id/edit_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ems="10" android:inputType="textPersonName" > <requestFocus /> </EditText> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/text_pass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text_pass" /> <EditText android:id="@+id/edit_pass" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:ems="10" android:inputType="textPassword" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/btn_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_login" /> <CheckBox android:id="@+id/chex_remember" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="80dp" android:text="@string/chex_remember" /> </LinearLayout> </LinearLayout>
2、界面布局中引用的string的属性
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">lession02-file</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> <string name="text_name">用户名:</string> <string name="text_pass">密 码:</string> <string name="btn_login">登录</string> <string name="chex_remember">记住密码</string> </resources>
3、封转的util中的读取文件
package com.example.utils; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; public class StreamTools { public static String getValue(FileInputStream fis) throws Exception{ //字节的输出流对象 ByteArrayOutputStream stream=new ByteArrayOutputStream(); byte[] buffer=new byte[1024]; int length=-1; while((length=fis.read(buffer))!=-1){ stream.write(buffer,0,length); } stream.flush(); stream.close(); String value=stream.toString(); return value; } }
4、service中的四种文件模式
package com.example.lession02_service; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.HashMap; import java.util.Map; import com.example.utils.StreamTools; import android.content.Context; public class FileService { //上下文的对象 public Context context; public FileService(Context context) { super(); this.context = context; } /** * 往手机内存上存储用户名和密码的操作 */ public boolean saveRom(String name,String pass,String fileName){ try{ //通过openFileOutput()方法获取一个文件的输出流对象 FileOutputStream fos=context.openFileOutput(fileName, Context.MODE_PRIVATE); //拼接用户名与密码 String result=name+":"+pass; //写入 fos.write(result.getBytes()); fos.flush(); fos.close(); }catch(Exception e){ e.printStackTrace(); return false; } return true; } //读取数据 public Map<String,String> readFile(String fileName){ Map<String,String> map=null; try{ FileInputStream fis=context.openFileInput(fileName); String value=StreamTools.getValue(fis); String values[]=value.split(":"); if(values.length>0){ map=new HashMap<String, String>(); map.put("name",values[0]); map.put("pass",values[1]); } }catch(Exception e){ e.printStackTrace(); } return map; } //追加模式 public boolean saveRomappend(String name,String pass,String fileName){ try{ //通过openFileOutput()方法获取一个文件的输出流对象 FileOutputStream fos=context.openFileOutput(fileName, Context.MODE_APPEND); //拼接用户名与密码 String result=name+":"+pass; //写入 fos.write(result.getBytes()); fos.flush(); fos.close(); }catch(Exception e){ e.printStackTrace(); return false; } return true; } }
5、LoginActivity中的代码
package com.example.lession02_file; import java.util.Map; import com.example.lession02_service.FileService; import android.os.Bundle; import android.app.Activity; import android.support.v4.widget.SimpleCursorAdapter.ViewBinder; import android.text.TextUtils; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Toast; public class LoginActivity extends Activity { //声明 获取用户名和密码的组件 public EditText edit_name,edit_pass; //声明获取登录按钮的组件 public Button btn_login; //声明获取复选框的组件 public CheckBox chex_remember; //创建业务对象 public FileService fileService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置显示的视图 setContentView(R.layout.activity_login); //实例化业务对象 fileService = new FileService(this); //根据id获取相应的组件 edit_name=(EditText) findViewById(R.id.edit_name); edit_pass=(EditText) findViewById(R.id.edit_pass); btn_login=(Button) findViewById(R.id.btn_login); chex_remember=(CheckBox) findViewById(R.id.chex_remember); //登录按钮的注册事件 btn_login.setOnClickListener(new MyOnClickListener()); //回显数据 Map<String,String> map = fileService.readFile("private.txt"); if(map!=null){ edit_name.setText(map.get("name")); edit_pass.setText(map.get("pass")); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.login, menu); return true; } //内部类 class MyOnClickListener implements View.OnClickListener{ @Override public void onClick(View v) { int id=v.getId(); if(id==btn_login.getId()){ //获取用户名和密码 String name=edit_name.getText().toString(); String pass=edit_pass.getText().toString(); //再判断用户名和密码是否为空 if(TextUtils.isEmpty(name)||TextUtils.isEmpty(pass)){ Toast.makeText(LoginActivity.this, "用户名或密码不能为空", Toast.LENGTH_LONG).show(); return; }else{ //如果记住密码勾选上了 if(chex_remember.isChecked()){ //调用业务对象的业务方法 LoginActivity.this.fileService.saveRom(name, pass, "private.txt"); Toast.makeText(LoginActivity.this, "用户名和密码需要保存", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(LoginActivity.this, "用户名和密码不需要保存", Toast.LENGTH_LONG).show(); } } } } } }