Android中的数据存储方式有5种,分别是文件存储、SharedPreferences、SQLite数据库、ContentProvider、网络存储。
每种存储方式有不同的特点,在这里简单介绍一下:
-
文件存储 :以I/O流形式把数据存入手机内存或者SD卡,可以存储大数据,如音乐、图片或视频等。
-
SharedPreferences:它本质上是一个XML文件,以键值对形式存入手机内存中。常用于存储较简单的参数设置,如QQ登录账号密码的存储、窗口功能状态的存储等,使用起来简单方便。
-
SQLite数据库 :是一个轻量级数据库,可跨平台,占用内存小,支持基本SQL语法,支持大部分的语言,是项目中经常被采用的一种数据存储方式,通常用于存储用户信息等。
-
ContentProvider:又称内容提供者,是Android四大组件之一,以数据库形式存入手机内存,可以共享自己的数据给其他应用使用。相对于其他对外共享数据的方式而言, ContentProvider统一了数据访问方式,使用起来更规范。
-
网络存储 :把数据存储到服务器,不存储在本地,使用时直接从网络获取。
本文主要介绍文件存储。
文件存储是Android中最基本的数据存储方式,与java中的文件存储类似,都是通过I/O流的形式把数据原封不动的存储到文档中。 文件存储可存在设备内部的存储空间中,即内部存储,也可存入到外置的SD卡中,即外部存储。这两种存储方式的主要区别在于,外部存储比内部存储多了一个确认设备是否可用的步骤,其余的输入输出都与内部存储类似。
1.内部存储
内部存储创建的文件保存在/data/data//files目录下。内部存储方式存储的文件被创建的应用程序私有,其他程序若要使用需设置权限。当应用程序被卸载时,内部存储文件也被随之删除。
内部存储使用openFileOutput()和openFIleInput()方法,获得FileOutputStream对象和FileInputStream对象,两个方法的形式如下:
FlieOutputStream openFileOutput(String name,int mode);
FileInputStream openFileInput(String name);
上述两个方法中,openFileOutput()用于打开应用程序中对应的输出流,存储数据;openFIleInput()用于打开对应输入流,读取数据。
其中,name表示文件名,mode表示读写文件的方式,取值有如下四种:
- MODE_PRIVATE: 该文件只能被当前文件读写,且不能追加,每一次都会覆盖原文件,默认的操作模式。
- MODE_APPEND: 会检查文件是否存在,存在就追加内容,否则创建新文件,常用的一种模式。
- MODE_WORLD_READABLE: 用来控制其他应用是否有权限读该文件,安全性低,通常不使用。
-
MODE_WORLD_WRITEABLE: 用来控制其他应用是否有权限写该文件,安全性低,通常不使用。
Flie类方法(包括内部和外部)介绍示例
File file = this.getFilesDir(); //获得当前程序默认文件存储目录,即/data/data/<package name>/files
File file = this.getCacheDir(); //获得默认缓冲文件存放位置,把一些不太重要的文件在此处创建、使用,
//内存不足时系统会自动删去APP的cache目录的数据
File file = this.getDir("name",MODE_APPEND); //创建一个目录在/data/data/<package name>/files之下
File file = this.getExternalCacheDir(); //可以得到外部的存储位置,该位置的数据跟内置的使用相同。
//若APP卸载,此数据也会自动清除
存储数据示例代码
String fileName="data.txt"; //文件名称
String context="helloworld"; //要保存的数据
FileOutputStream fos;
try{
fos = openFileOutput(fileName,MODE_PRIVATE); //打开程序的输出流,存储数据到data.txt,以私有模式
//若希望文件被其他应用读和写,可以传入MODE_WORLD_READABLE+MODE_WORLD_WRITEABLE
fos.write(content.getBytes)); //向fos对象写入context的内容,以二进制形式保存
fos.close(); //关闭输出流
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOEception e) {
e.printStackTrace();
}
读取文件示例代码
String fileName="data.txt"; //文件名称
String context=null; //用于保存读取出来的数据
FileInputStream fis;
try{
fis = openFileInput(fileName); //打开程序的输出流,存储数据到data.txt
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//可以捕获内存缓冲区的数据,转换成字节数组。
byte[] buffer = new byte[1024]; //每次读1024字节
int len=0; //初始长度定义为0
while((len = fis.read(buffer))!=-1) { //如果buffer里面还有值
baos.write(buffer,0,len); //就从buffer里,将0~len的值全部写到baos里
}
context = baos.toString(); //将baos中的数据写出去
fis.close(); //关闭输出流
baos.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOEception e) {
e.printStackTrace();
}
2.外部存储
外部存储是指将文件存储到一些外围设备上(通常位于mnt/sdcard目录下)。由于外围存储设备可能被移除、丢失或者处于其他状态,因此在使用外围设备之前必须使用Environment.getExternalStorageState()方法来确认外围设备是否可用,当外围设备可用并且具有读写权限时,就可以通过FileInputStream、FileOutputStream或者FileReader、FileWriter对象来读写外围设备中的文件,此时和内部存储的方式相同。
向外围设备中存储数据的示例代码如下
String state = Environment.getExternalStorageState();
if(state.equals(Environment.MEDIA_MOUNTED)) { //确认外围设备是否可用
File SDPath = Environment.getExternalStorageDirectory(); //获取SD卡根目录路径
File file = new File(SDPath,"data.txt");
String data = "HelloWorld";
FileOutputStream fos;
try{
fos = new FileOutputStream(file);
fos.write(data.getBytes());
fos.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOEception e) {
e.printStackTrace();
}
}
从外围设备读取数据示例代码
String state = Environment.getExternalStorageState();
if(state.equals(Environment.MEDIA_MOUNTED)) { //确认外围设备是否可用
File SDPath = Environment.getExternalStorageDirectory(); //获取SD卡根目录路径
File file = new File(SDPath,"data.txt");
String data = "HelloWorld";
FileInputStream fis;
try{
fis = new FileOutputStream(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //与内部存储相同
byte[] buffer = new byte[1024];
int len=0;
while((len = fis.read(buffer))!=-1) {
baos.write(buffer,0,len);
}
String context = baos.toString();
fis.close();
baos.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOEception e) {
e.printStackTrace();
}
}
需要注意的是,如果程序需要访问系统的一些关键信息,必须要在清单文件声明权限才可以,否则程序会直接崩溃。操作SD卡中的数据就是系统中比较关键的信息,因此需要在清单文件的节点下配置权限信息,具体代码如下:
<user-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<user-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>