Android的数据存储之SharedPreference与文件File的基本使用
Android的数据存储方式大概分为5种:文件File、网络、SharedPreference、SQLite(数据库)和内容提供者。本节介绍SharedPreference与文件File的基本使用。
1、SharedPreference的基本使用:
sharedPreference是一种轻量级的数据储存方式,使用比较简单。使用比较经典的场景如登录的例子。
(1)、通过getSharedPreferences获取SharedPreferences对象(获取画布)
SharedPreferences sp=context.getSharedPreferences("sharefile.txt",Context.MODE_PRIVATE);
(2)找到画笔:
SharedPreferences.Editor editor = sp.edit();
(3.1)在画布上画,并提交:
//id用于标识内容des
editor.putString(id,des);
//提交,数据被写入文件中
editor.commit();
(3.2)通过id寻找数据:
//找不到数据时默认为null
sp.getString(id,null);
整体代码如下:
package com.example.androidstorgetest;
import android.content.Context;
import android.content.SharedPreferences;
public class sharepreferenceUtils {
private static sharepreferenceUtils spu;
private SharedPreferences sp = null;
private SharedPreferences.Editor editor = null;
private Context context;
private String id = "id";
private sharepreferenceUtils(Context context)
{
this.context = context;
sp=context.getSharedPreferences("sharefile.txt",Context.MODE_PRIVATE);
editor = sp.edit();
}
public static sharepreferenceUtils getInstance(Context context)
{
if (spu == null)
return spu=new sharepreferenceUtils(context);
else
return spu;
}
public String getData()
{
return sp.getString(id,null);
}
public void putData(String des)
{
editor.putString(id,des);
editor.commit();
}
}
这里只列出了一种写数据和读数据的方式,其中写数据还有如下一些方法,可根据需要来使用,
2、文件File储存的基本使用
使用文件存储用得较多的是Android提供的openFileInput和openFileOutput两个类,下面通过通过一个例子演示如何使用这两个类。
效果如图,通过按钮先写将“123456789abcdefghijklmn”写入文件再读出来,显示在textview控件上。
//包装两个方法来调用
public String readDataUseBuffer(String filename) throws IOException {
FileInputStream inputStream = mContext.openFileInput(filename);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String str = "";
StringBuilder builder = new StringBuilder();
while ((str = reader.readLine()) != null)
builder.append(str);
reader.close();
inputStream.close();
return builder.toString();
}
public boolean writeDataUseBuffer(String data,String filename) throws IOException {
FileOutputStream outputStream = mContext.openFileOutput(filename,Context.MODE_PRIVATE);
BufferedWriter writer =new BufferedWriter(new OutputStreamWriter(outputStream));
writer.write(data);
writer.close();
outputStream.close();
return true;
}
//调用方法:fileObject是两个方法的实体类
fileObject.writeDataUseBuffer("123456789abcdefghijklmn","data");
Thread.sleep(1000);
String str = fileObject.readDataUseBuffer("data");
tv.setText(str);
先看写数据进文件,创建一个openFileoutput对象,传入文件名和权限(权限主要有两种:MODE_PRIVATE私有、MODE_APPEND在文件尾追加),再用BufferedWriter来包装这个数据流对象(关于数据流的操作跟Java一样,在后面复习讲),调用write来写入数据。
对读出数据,同样创建一个openFileInput对象,传入文件名和权限,再用BufferReader来包装这个流方便操作。
使用得比较频繁的还有FileInputStream和FileOutStream这两个类,如下,同样通过写成两个方法来操作数据演示如何使用。
public String ReadData(String filename) throws IOException {
FileInputStream inputstream = new FileInputStream(filename);
byte[] data = new byte[1024];
while (inputstream.read(data) != -1);
String str = new String(data);
//关闭流
inputstream.close();
/*inputstream.read(data);*/
/*读取全部值
* public int read(byte b[])
*读取时偏移量和长度
* public int read(byte b[], int off, int len)
* */
return str;
}
public boolean writeData(String data,String filename) throws IOException {
File file = new File(filename);
if (!file.exists())
{
file.createNewFile();
if (!file.exists())
return false;
}
FileOutputStream outputStream = new FileOutputStream(filename);
outputStream.write(data.getBytes());
//关闭流
outputStream.close();
return true;
}
//调用方法来写数据
if(!fileObject.writeData("1234567890abcdefghijklmnopqrstuvwz",getFilesDir().getPath()+"/file.txt")){
Log.e("tag","file not found");
return;
}
Thread.sleep(1000);
String readData=fileObject.ReadData(getFilesDir().getPath()+"/file.txt");
tv.setText(readData);
这里没有包装流,直接操作。需要注意的是,这两个类不会自动创建文件,如果文件没有需要先判断文件是否存在再操作文件。
判断文件是否存在和创建一个文件可调用如下两个方法:
File file = new File(filename);
if (!file.exists())
{
file.createNewFile();
}
除了上面使得比较频繁的类,在加载Android资源常常会用到下面的方法:
//获取Assets资源
InputStream in = mContext.getResources().getAssets().open(fileName);
//获取raw资源
InputStream in = getResources().openRawResource(R.raw.read_raw);
文件路径问题:
* 方法:getDataDirectory()返回 File ,获取 Android 数据目录。
* 方法:getDownloadCacheDirectory()返回 File ,获取 Android 下载/缓存内容目录。
* 方法:getExternalStorageDirectory()返回 File ,获取外部存储目录即 SDCard
* 方法:getExternalStoragePublicDirectory(String type)返回 File取一个高端的公用的外部存储器目录来摆放某些类型的文件
* 方法:getExternalStorageState()返回 File ,获取外部存储设备的当前状态
* 方法:getRootDirectory()返回 File ,获取 Android 的根目录
*方法Context.getFilesDir(),返回/data/data/PackageName/files的File对象。
*方法Context.getCacheDir()返回/data/data/PackageName/cache的File对象。
补充:复习Java流
Android的流程操作跟Java一样,这里补充总结一下Java流操作。
Java的io流可分为:
(1)、输入流和输出流 (从CPU的角度去考虑问题) (2)、字节流和字符流 byte(8位) char(16位)
根据上面的分类的结合,Java IO流主要分为4大类:
字节输入流:抽象基类是InputStream
字节输出流:抽象基类是OutputStream
字符输入流:抽象基类是Reader
字符输出流:抽象基类是Writer
实体使用:
向文件输入输出,则使用如下的类:FileInputStream、FileOutputStream、FileReader、FileWriter
向数组输入输出:ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter
向管道输入输出:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
字符串:StringReader、StringWriter
缓冲区:BufferedInputStream、BuferedOutputStream、BuferedReader、BufferedWriter
转换流:
InputStreamReader 字节输入流转字符输入流
OutputStreamWriter 字节输出流转字符输出流
对象流(对象序列化):
ObjectInputStream 对象输入流
ObjectOutputStream 对象输出流
有时需要对一个流进行包装,例如上面文件操作BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));是对inputStream流进行包装,使得流的效率更高,更加方便数据操作。
几种流的关系如下图:
包装流的原理如下图:
关于流的操作比较灵活,视需要运用即可。