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();

后果:

<map> <string name="data">我是Rocky</string></map>

第五步:获取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权限须要动静获取

//可写<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />//可读<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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:
在强人的眼中,没有最好,只有更好