Android 数据存储之SP存储,内部存储,外部存储

Android提供了多种数据存储的技术来永久的保存应用数据,以便于开发者能够根据自己的需求来选择合适的数据存储方案,主要有SharedPreferences,内部存储(Internal Storage),外部存储(External Storage),SQLite数据库网络存储等

一:SharedPreferences

第一步:getSharedPreferences方法获取到SharedPreferences对象。系统会在/data/data/包名/shared_prefs目录下生成一个**文件

Context.MODE_PRIVATE:默认的文件创建模式。使用该模式创建文件,如果文件目录中已存在同名文件,则新建的文件会覆盖旧文件。并且,文件只能由创建文件的应用(或者与该应用共享同一user ID的应用)所访问。
Context.MODE_APPEND:使用该模式创建文件,如果文件目录中已存在同名文件,则新的内容将直接被添加到旧文件的尾部,而不会新建一个文件来覆盖旧文件。
Context.MODE_WORLD_READABLE:使其他应用对文件具有读的权限。
Context.MODE_WORLD_WIRTEABLE:使其他应用对文件具有写的权限。
注意:从API Level 17以后,MODEWORLDREADABLE和MODEWORLDWRITEABLE已经被弃用。从Android N(即7.x)开始,使用这两个常量会导致SecurityException。这意味着面向Android N和更高版本的应用无法按名称共享私有文件,尝试共享“file://"类型的URI将会导致FileUriExposedException。
第二步:通过SharedPreferences对象的edit()方法获取一个SharedPreferences.Editor对象
第三步:调用putBoolean()(或者putString()、putInt()等,由要保存的数据的数据类型而定)等方法添加值

第四步:使用提交commit()方法有返回值boolean类型和apply()无返回值

/*获取SharedPreferences对象1.第一个参数为name:表示文件名,系统会在/data/data/包名/shared_prefs目录下生成一个以该参数命名的.xml文件2.第二个mode表示创建的模式,建议为0或者MODE_PRIVATE* */SharedPreferences sp = getSharedPreferences("test_sp", MODE_PRIVATE);//获取Editor对象SharedPreferences.Editor editor = sp.edit();//根据要保存的数据类型,调用对应的put方法//以键值对形式添加editor.putString("data", "我是Rocky");//提交新值,必须执行否则前面操作无效editor.commit();

结果:

 我是Rocky

第五步:获取SP数据

//根据保存时所用的name属性,获取SharedPreferences对象SharedPreferences sp=getSharedPreferences("test_sp",MODE_PRIVATE);//根据数据类型,调用对应的get方法,通过键取得对应的值。String aa=sp.getString("data",null);Log.d("aa",aa);结果:D/aa: 我是Rocky
二:内部存储

内部存储创建私有文件:文件目录/data/data/包名/files
写入文件test_file

//文件名String file_name="test_file";//写入内容String content="Hello Android!";try {    //写出数据,以程序为中心,写出数据到文件中 FileOutputStream fos=openFileOutput(file_name,MODE_PRIVATE); //调用write写入数据 fos.write(content.getBytes()); //调用close()关闭数据流 fos.close();} catch (FileNotFoundException e) {    e.printStackTrace();} catch (IOException e) {    e.printStackTrace();}结果:Hello Android!


要从内部存储中读取文件,步骤如下:
1.使用要读取的文件的文件名作为参数,调用openFileInput()方法,返回一个FileInputStream实例。
2.调用read()方法读取文件字节。

3.字节数组转成String类型
4.调用close()方法关闭流式传输。

private FileInputStream fis;//用于存储数据流的byte数组byte[] bytes=new byte[1024];//1024个字节数组是1kBint read=0;//得到时间读取的字节数,读带最后返回-1;try {    //调用openFileInput,返回一个FileInputStream fis = openFileInput(file_name);  //循环读取 while ((read= fis.read(bytes))!=-1){//把fis里的东西读到bytes数组里去        // //把字节转成String 从0到read变成String String s=new String(bytes,0,read); Log.d("s",s); }} catch (FileNotFoundException e) {    e.printStackTrace();} catch (IOException e) {    e.printStackTrace();}finally {    try {        fis.close(); } catch (IOException e) {        e.printStackTrace(); }}结果:D/s: Hello Android!

注意:文件的读写操作是耗时操作,因此最好不要在主线程(UI线程)中执行,避免程序出现ANR(程序未响应)。并且,在每次操作结束后,要记得调用close()方法关闭对应的输入流或者输出流,以释放系统资源。

三:内部存储缓存文件

文件目录:data/data/包名/cache
    当有一些文件只需临时使用,不必永久保存的时候,应该把这些文件保存在内部存储的缓存目录中。保存在内部存储的缓存目录中的文件,当设备内部存储空间不足时,系统可能会首先删除这些缓存文件以释放内存空间。但是,开发者不应该依赖系统来清理这些文件,而应该始终自行维护缓存文件,使其占用的空间保持在合理的限制范围内(如1MB)。当应用被卸载时,缓存文件也会被移除。

//文件名String file_cache_name="test_cache_file";//写入内容String cache_content="Hello Cache World";//使用getCacheDir()方法获取内部存储缓存目录File cacheDir=getCacheDir();//这个拿到得是cache目录结构//构造文件路径,/data/data/包名/cache/文件名//通过这种方式指明文件要保存在内部存储缓存目录中。String cache_file=cacheDir+"/"+file_cache_name;try {    //通过FileOutputStream的构造方法传入构造好 //的文件路径,返回一个FileOutputStream实例。 //注意:这里没有再使用openFileOutput,是因 //为openFileOutput参数不允许包含路径分隔符“/”, //如果继续使用openFileOutput方法,将会出现 //IllegalArgumentException异常 FileOutputStream cache_fos=new FileOutputStream(cache_file); //调用write()方法写入数据 cache_fos.write(cache_content.getBytes()); //调用close()关闭输出流 cache_fos.close();} catch (FileNotFoundException e) {    e.printStackTrace();} catch (IOException e) {    e.printStackTrace();}结果:Hello Cache World

读取内部存储缓存目录文件的缓存文件

//文件名String file_cache_name="test_cache_file";private FileInputStream inputStream;//用于存储数据流的byte数组byte[] bytes=new byte[1024];int read=0;//得到时间读取的字节数,读带最后返回-1;try {    File cache=getCacheDir(); String cache_file=cache+"/"+file_cache_name; inputStream = new FileInputStream(cache_file); while ((read= inputStream.read(bytes))!=-1){        // //把字节转成String 从0到read变成String String c=new String(bytes,0,read); Log.d("c",c); }} catch (FileNotFoundException e) {    e.printStackTrace();} catch (IOException e) {    e.printStackTrace();}finally {    try {        inputStream.close(); } catch (IOException e) {        e.printStackTrace(); }}结果: D/c: Hello Cache World

对于内部存储中文件和目录的操作实用的方法
getFilesDir():获取存储内部文件的文件系统目录的绝对路径。即 /data/data/包名/files
getDir(String name,int mode):在内部存储空间中新建(或打开现有的)目录。即在 data/data/包名 目录下新建(或打开现有的)目录
deleteFile(String name):删除 /data/data/包名/files目录下name属性指定的文件。此方法参数不能包含路径分隔符“/”,直接传入要删除的文件的文件名即可。
fileList():列出 /data/data/包名/files目录下所有文件的文件名。

四:外部存储(External Storage)

所有的兼容Android的设备都支持一个共享的能够让用户保存文件的外部存储。这个外部存储可能是一个可移植的存储介质(SD卡),或者是系统在自身的内部存储器上所分配出来用作外部存储的分区。包括设备上的一些公共目录,如手机相册(Pictures),音乐(Music)等目录。存储在外部存储中的文件是全局可读写文件。
1.外部存储需要添加访问权限,在AndroidManifest.xml文件中,Android6.0权限需要动态获取

//可写//可读

2.判断当前设备的状态
Environment.getExternalStorageState() 返回外部存储设备当前的状态
Environment.getDataDirectory() 返回file,获取data的根目录
Environment.getRootDirectory() 返回 File ,获取 Android 的根目录
D/aa: mounted
D/aa: /data
D/aa: /system
Environment.MEDIA_MOUNTED 等于"mounted",代表SD卡挂载,可读写
Environment.MEDIA_UNMOUNTED 等于"unmounted",有介质未挂载 不可读写

//获取外部存储的可用性String state=Environment.getExternalStorageState();if (Environment.MEDIA_MOUNTED.equals(state)){    return true;}

3.获取外部存储相册的路径

File picDirectory2= getExternalFilesDir(Environment.DIRECTORY_PICTURES);//获取设备的相册目录File picDirectory =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);Log.d("aa",picDirectory2.getAbsolutePath());Log.d("aa",picDirectory.getAbsolutePath());结果:D/aa: /storage/emulated/0/Android/data/com.ruan.testw/files/PicturesD/aa: /storage/emulated/0/Pictures
//获取外部设备的状态String state=Environment.getExternalStorageState();//如果外设可以用if (Environment.MEDIA_MOUNTED.equals(state)){    File picDirectory2= getExternalFilesDir(Environment.DIRECTORY_PICTURES); //获取设备的相册目录 File picDirectory =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); Log.d("aa",picDirectory2.getAbsolutePath()); Log.d("aa",picDirectory.getAbsolutePath()); File file=new File(picDirectory2,"My_pic");//第一个参数父文件,第二个文件是子文件 if (!file.exists()){//如果文件不存在,创建一个新的文件 try {            file.createNewFile(); } catch (IOException e) {            e.printStackTrace(); }    }
File picDirectory3= getExternalCacheDir();Log.d("aa",picDirectory3.getAbsolutePath());结果:D/aa: /storage/emulated/0/Android/data/com.ruan.testw/cache
//获取外部设备的状态String state=Environment.getExternalStorageState();String cont="我在外部存储文件中";//如果外设可以用if (Environment.MEDIA_MOUNTED.equals(state)){    String file_path=Environment.getExternalStorageDirectory().getAbsolutePath();    Log.d("aa",file_path);    }File file=new File(file_path+"/"+"My_Test");if (!file.exists()){        file.mkdir();//创建文件夹}else {    FileOutputStream fileOutputStream= null; try {        File file1=new File(file,"wo"); fileOutputStream = new FileOutputStream(file1); fileOutputStream.write(cont.getBytes()); fileOutputStream.flush(); fileOutputStream.close(); } catch (FileNotFoundException e) {        e.printStackTrace(); } catch (IOException e) {        e.printStackTrace(); }}结果:内容写入到D/aa: /storage/emulated/0/My_Test/wo文件下我在外部存储文件中

总结:
1.Environment.getExternalStorageDirectory() 获取外部存储的目录
/storage/emulated/0
2.Environment.getRootDirectory()获取存储的系统system目录
/system
3.Environment.getDataDirectory()获取data目录
/data
4.Environment.getDownloadCacheDirectory()获取data目录下
/data/cache
5.getExternalCacheDir()//获取外部存储包名下的cache
/storage/emulated/0/Android/data/com.ruan.testw/cache
6.getCacheDir()获取内部存储下cache
/data/data/com.ruan.testw/cache
7.getFilesDir()获取内部存储下files
/data/user/0/com.ruan.testw/files=/data/data/com.ruan.testw/files
8.getExternalFilesDir(Environment.DIRECTORY_DCIM)获取外部存储的包名下files文件//参数是一个String的“aa”都可以
/storage/emulated/0/Android/data/com.ruan.testw/files/DCIM
9.getSharedPreferences("test_sp", MODE_PRIVATE);获取SharedPreferences对象
/data/data/包名/shared_prefs/test_sp
END:
在强者的眼中,没有最好,只有更好

更多相关文章

  1. AIDL(android 接口定义语言)
  2. Android下获取开机时间
  3. Android(安卓)Studio 小技巧(1):如何导入AAR文件
  4. 文件操作与SDCard读写访问
  5. 配置android jni开发环境
  6. Android(安卓)Studio版本控制指南
  7. android播放音频文件(MediaPlayer)和录音(MediaRecorder)--播放
  8. NPM 和webpack 的基础使用
  9. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程

随机推荐

  1. Android Cloud to Device Messaging Fram
  2. 高德天气应用开发之一:android 应用子功能
  3. android内存溢出的解决方法(转)
  4. 给Android增加分享库.so文件
  5. Android -- android app 能分配的最大内
  6. Android Content Provider[转]
  7. android中的LayoutInflater
  8. Android之Android studio动态搜索添加依
  9. 《Android》Lesson19-广播1
  10. Android之常用开发框架