数据存储与访问之文件的存储和访问

一、首先给大家介绍使用文件如何对数据进行存储,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();
					}
				}
			}
		}
		
	}

}



 

你可能感兴趣的:(数据存储与访问之文件的存储和访问)