数据在这个时代,我相信大家一定都不陌生。
今天,我们来探讨一下有关数据的存储的知识。数据存储主要分为可持久化和临时存储,临时存储是数据只作临时使用不作保存,如在内存的数据,或者某些计算的中间值,持久化数据是指数据被保存下来,可以被以任何形式保存。
今天我们主要学习以文件形式保存数据,其实也只是学习一下安卓中的一些简单的函数api。
我们来模拟一下用户登陆的场景,用户登陆需要输入用户名和密码,然后点击登陆便可以了,为此,我们可以设计如下界面:
该界面对应的布局文件代码如下:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/userName"
/>
<EditText
android:id="@+id/et_pwd"
android:layout_below="@id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/userPwd"
android:inputType="textPassword"
/>
<Button
android:id="@+id/bt_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/saveAsC"
android:layout_below="@id/et_pwd"
android:layout_alignParentLeft="true"
/>
<Button
android:id="@+id/bt_save_s"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/saveAsS"
android:layout_below="@id/et_pwd"
android:layout_alignParentRight="true"
/>
<Button
android:id="@+id/bt_save_xml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/saveAsXML"
android:layout_below="@id/et_pwd"
android:layout_toRightOf="@id/bt_save"
android:layout_toLeftOf="@id/bt_save_s"
/>
</RelativeLayout>
strings.xml代码如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SavaDate</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="userName">请输入用户名</string>
<string name="userPwd">请输入用户密码</string>
<string name="saveAsC">保存到内存</string>
<string name="saveAsS">保存到SD卡</string>
<string name="saveAsXML">XML</string>
</resources>
由于对文件操作可能时常用到,故我们可以把对文件的操作提取出来
FileService.java
package com.hackerant.service;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Environment;
public class FileService
{
private static final String FILENAME = "info.txt";
/**
* 将用户信息保存到相应文件下
* @param context
* @param userName
* @param userPwd
* @return
*/
public static boolean saveToCache(Context context,String userName,String userPwd){
//1、生成要保存的文件
//通常的java2e生成文件是这样的
// File file = new File(path); //在这个方法里,需要写入具体的路径,如c:/abc.txt
//Android里提供了关于文件地址的api,分别是context.getCacheDir();context.getFilesDir();
//分别表示将文件存到缓存路径和文件路径,缓存路径当用户清理缓存的时候便会将文件都清除,而文件路径下的文件
//则必须手动删除
try
{
//普通java2e写文件方法
//File file = new File(context.getCacheDir(), FILENAME);
// FileOutputStream fos = new FileOutputStream(file);
//Android的api写文件方法,其中mode分为MODE_PRIVATE,表示私有,仅自己可以调用,MODE_APPEND,
//追加模式,MODE_WORLD_READABLE,可读,MODE_WORLD_WRITEABLE ,可写
FileOutputStream fos = context.openFileOutput(FILENAME, context.MODE_PRIVATE);
fos.write((userName + "##" + userPwd).getBytes());
fos.close();
return true;
} catch (Exception e)
{
e.printStackTrace();
return false;
}
}
/**
* 读取文件信息
* @param context
* @return
*/
public static String [] getFileInfo(Context context){
String [] arr = {};
try
{
// File file = new File(context.getCacheDir(), FILENAME);
FileInputStream fis = context.openFileInput(FILENAME);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
arr = br.readLine().split("##");
} catch (Exception e)
{
e.printStackTrace();
}
return arr;
}
/**
* 保存文件到内存卡
* @param userName
* @param userPwd
*/
public static boolean savaToSD(String userName,String userPwd){
try
{
//获取内存卡状态
//Environment.getExternalStorageDirectory()获取外部存储路径
String statue = Environment.getExternalStorageState();
//如果内存卡当前可用(正确挂载)
if (Environment.MEDIA_MOUNTED.equals(statue))
{
File file = new File(Environment.getExternalStorageDirectory(), FILENAME);
FileOutputStream fos = new FileOutputStream(file);
fos.write((userName + "##" + userPwd).getBytes());
fos.close();
return true;
}
} catch (Exception e)
{
e.printStackTrace();
}
return false;
}
/**
* 保存文件到内存,xml文件
* @param userName
* @param userPwd
*/
public static boolean savaAsXML(String userName,String userPwd,Context context){
try
{
//获取内存卡状态
String statue = Environment.getExternalStorageState();
//如果内存卡当前可用(正确挂载)
if (Environment.MEDIA_MOUNTED.equals(statue))
{
//获取SharedPreferences的编辑器
SharedPreferences sp = context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE);
Editor editor = sp.edit();
editor.putString("userName", userName);
editor.putString("userPwd", userPwd);
//记得一定要提交
editor.commit();
return true;
}
} catch (Exception e)
{
e.printStackTrace();
}
return false;
}
}
MainActivity.java
package com.hackerant.savadate;
import com.hackerant.service.FileService;
import android.os.Bundle;
import android.app.Activity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener
{
private EditText etName;
private EditText etPwd;
private Button btSaveC;
private Button btSaveS;
private Button btSaveXml;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取对象值
etName = (EditText) findViewById(R.id.et_name);
etPwd = (EditText) findViewById(R.id.et_pwd);
btSaveC = (Button) findViewById(R.id.bt_save);
btSaveS = (Button) findViewById(R.id.bt_save_s);
btSaveXml = (Button) findViewById(R.id.bt_save_xml);
//先尝试读取文件,如果存在,则展现出来
String arr[] = FileService.getFileInfo(this);
//判断是否存在,如果存在则展现,如果不存在,则不展现
if (arr != null && arr.length > 0)
{
etName.setText(arr[0]);
etPwd.setText(arr[1]);
}
//设置点击事件
btSaveC.setOnClickListener(this);
btSaveS.setOnClickListener(this);
btSaveXml.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
//保存到手机内存
case R.id.bt_save:
String userName = etName.getText().toString().trim();
String userPwd = etPwd.getText().toString().trim();
if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userPwd))
{
Toast.makeText(getApplicationContext(), "用户名或密码不能为空!", Toast.LENGTH_SHORT)
.show();
}else {
FileService.saveToCache(this, userName, userPwd);
Toast.makeText(getApplicationContext(), "保存信息成功", Toast.LENGTH_SHORT)
.show();
etName.setText("");
etPwd.setText("");
}
break;
//保存到SD卡
case R.id.bt_save_s:
String name = etName.getText().toString().trim();
String pwd = etPwd.getText().toString().trim();
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd))
{
Toast.makeText(getApplicationContext(), "用户名或密码不能为空!", Toast.LENGTH_SHORT)
.show();
}else {
FileService.savaToSD(name, pwd);
Toast.makeText(getApplicationContext(), "保存信息成功", Toast.LENGTH_SHORT)
.show();
etName.setText("");
etPwd.setText("");
}
break;
//以xml的形式保存
case R.id.bt_save_xml:
String name_xml = etName.getText().toString().trim();
String pwd_xml = etPwd.getText().toString().trim();
if (TextUtils.isEmpty(name_xml) || TextUtils.isEmpty(pwd_xml))
{
Toast.makeText(getApplicationContext(), "用户名或密码不能为空!", Toast.LENGTH_SHORT)
.show();
}else {
FileService.savaAsXML(name_xml, pwd_xml, getApplicationContext());
Toast.makeText(getApplicationContext(), "保存信息成功", Toast.LENGTH_SHORT)
.show();
etName.setText("");
etPwd.setText("");
}
break;
default:
break;
}
}
}
代码写好记得要去配置读取sd卡的权限,在此就不赘述了
结果:
三个按钮均点击一遍可在ddms下看到
说明:
使用前两种保存文件的方法会出现一些错误,如当用户名或者密码恰巧存在##的时候,我们的解析就会出错,如zs####123,用户名为zs##,密码为123,但我们解析出来的会变成用户名为zs,密码为空,这样就正确了,使用第三种方法保存文件,便不会出现以上问题,且第三种方法还会对一些字符进行转义,如<等,用户可以自己体现一把