一.文件存储
文件存储不对存储的内容进行处理,适合用于存储一些简单的文本数据或二进制数据。如果要存储较为复杂的文本数据,就要定义一套自己的格式规范。
1.将数据存储到文件中
Context类中有一个 openFileOutput(String name, int mode) 的方法,是用于将数据存储到指定的文件中,它的返回值为 FileOutputStream,其中有两个参数,前者表示文件名称(其中不能包含路径名,其路径都是在/data/data/包名/files/目录下),后者表示操作模式,有MODE_PRIVATE(默认模式,文件存在时覆盖其中的内容)和MODE_APPEND(文件存在,就往文件的末尾添加数据)两种。得到了 FileOutputStream 对象后就通过Java流将数据写入到文件。具体的实现如下:
// 将message信息写入到name为名的文件中
public void writeToFile(String name, String message) {
FileOutputStream fileOutputStream = null;
BufferedWriter bufferedWriter = null;
try {
fileOutputStream = openFileOutput(name, Context.MODE_PRIVATE);
bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
bufferedWriter.write(message);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static final String name = "file";
public static final String message = "message";
// 调用方法
writeToFile(name, message);
可以通过 Device File Explorer 工具查看是否生成了对应的文件。
2.将数据从文件中读取出来
使用Context类中的 openFileInput(String name) 方法,它的返回值为 FileInputStream,其中的参数表示文件名(其路径都是在/data/data/包名/files/目录下)。得到了 FileInputStream 对象后就通过Java流将数据从文件中读取出来。具体的实现如下:
// 从name文件中读取数据
public String readFromFile(String name) {
FileInputStream fileInputStream = null;
BufferedReader bufferedReader = null;
StringBuilder stringBuilder = new StringBuilder();
try {
fileInputStream = openFileInput(name);
bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return stringBuilder.toString();
}
public static final String name = "file";
// 调用方法
String message = readFromFile(name);
// 最后通过适当的方式处理message,这里就用log打印了一下
Log.d("MainActivity", message);
二.SharedPreferences存储(以下简称SP)
SP是用键值对的方式存储数据的。存储时要给数据提供键,读取时也要使用对应的键。
1.将数据存储到SP中
要使用SP存储数据,要先获取SP的对象,主要有3种方法得到SP对象:Context类的 getSharedPreferences(String name, int mode) , Activity类的 getPreferences(int mode),PreferenceManager类的静态方法 getDefaultSharedPreferences(Context context)。
1.1 三种方式的介绍
1.1.1 Context类的 getSharedPreferences(String name, int mode)
第一个参数是SP的名称(其路径都是在/data/data/包名/shared_prefs/目录下),第二个参数是操作模式,其中只有一种模式即 MODE_PRIVATE(默认操作模式,表明只有当前应用可以读写这个SP文件)。
1.1.2 Activity类的 getPreferences(int mode)
该方法实际是调用了Context类的 getSharedPreferences(String name, int mode) ,其中的name参数被设定为 getLocalClassName() ,表示的是以当前活动的类名作为SP的名称。
1.1.3 PreferenceManager类的静态方法 getDefaultSharedPreferences(Context context) ,该方法返回 context.getSharedPreferences(getDefaultSharedPreferencesName(context), getDefaultSharedPreferencesMode());
其中 getDefaultSharedPreferencesName(context) 返回 context.getPackageName() + "_preferences" , getDefaultSharedPreferencesMode() 返回 MODE_PRIVATE 。也就是说明最后是以当前包名+_preferences来作为SP的名称。
1.2 具体的存储实现步骤
1.获取SP对象sharedPreferences。
2.调用SP对象的 edit() 方法获取 SharedPreferences.Editor 对象editor。
3.向 SharedPreferences.Editor 对象editor中添加数据,使用 putXxx(String key, xxx value) 即可。比如存放int类型就通过 putInt(String key, int value) 即可。
4.调用SharedPreferences.Editor 对象editor的apply()方法提交添加的数据,完成数据存储。
具体实现如下:
SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("keyint", 123);
editor.putString("keyString", "abc");
editor.putBoolean("keyboolean", false);
editor.apply();
可以通过 Device File Explorer 工具查看是否生成了对应的文件,它是通过XML格式进行数据管理。
2. 从对应的sp的xml文件中读取数据
读取比较简单,直接通过SP对象sharedPreferences中的 getXxx(String key, xxx defValue) 来进行操作即可,它与SharedPreferences.Editor 对象editor中的 putXxx(String key, xxx value) 是相互对应的。
其中 getXxx(String key, xxx defValue) 方法第一个参数表示键值,第二个参数表示默认值。也就是说当在sp的xml文件中找不到相应的键,就会得到默认值。
具体实现如下:
SharedPreferences sharedPreferences = getSharedPreferences(getLocalClassName(), MODE_PRIVATE);
int keyInt = sharedPreferences.getInt("keyint", 100);
String keyString = sharedPreferences.getString("keyString", "aaa");
boolean keyBoolean = sharedPreferences.getBoolean("keyboolean", false);
float keyFloat = sharedPreferences.getFloat("keyFloat", 3.333f);
Log.d("show", keyInt + " " + keyString + " " + keyBoolean + " " + keyFloat);
根据1.2中的例子可以得出如下的结果:
前面三个的键都存在,所以默认值就没有用到,最后一个键不存在,所以用到默认值。