Android的存储----重新认识Android(9)

    xiaoxiao2021-04-18  61

    安卓的(持久化)存储机制: 1.共享参数存储SharedPreferences,一遍用于存储简单的键值对的配置信息,用户名.... 键值对的值限于int,long,String,float,boolean 2.内部存储Internal Storage,即存在手机的内存中.一遍用于存放一下不太大的文件. 手机存储: RAM:运行时内存.相当于pc机的内存,不是持久化存储的,里面的数据断点就消失. ROM:相当于pc机的硬盘 SD CARD:扩展存储卡. SharedPreferences共享参数   一、数据存储选项:Data Storage ——Storage Options 1、Shared Preferences  Store private primitive data in key-value pairs. 保存简单的键值对数据。 2、Internal Storage Store private data on the device memory. 在手机内存中保存不对外共享的信息。 3、External Storage Store public data on the shared external storage. 在外部存储设备上保存公共的数据信息。主要指保存在SDCard上。 4、SQLite Databases Store structured data in a private database. 将结构化的数据保存进数据库。   二、SharedPreferences: (一)、概念:         SharedPreferences是Android系统提供的一个通用的数据持久化框架,用于存储和读取 key-value 类型的原始基本数据类型的数据,目前支持 String、int、long、float、boolean 等基本类型的存储,对于自定义的对象数据类型,无法使用SharedPreferences来存储。         SharedPreferences主要用于存储系统的配置信息。例如上次登录的用户名,上次最后设置的配置信息(如:是否打开音效、是否使用振动,小游戏的玩家积分等)。当再次启动程序后依然保持原有设置。SharedPreferences用键值对方式存储,方便写入和读取。   (二)、使用SharedPreferences的步骤: 1、获取SharedPreferences对象;         SharedPreferences本身是一个接口,无法直接创建实例,通过 Context 中定义的实例方法 getSharedPreferences (String name, int  mode)方法来获取实例。         该方法的第二个参数表示 文件读写的操作模式,传入: Context. MODE_PRIVATE :  指定该SharedPreferences的数据只能被本应用程序读、写; 2、调用edit()方法获取 SharedPreferences.Editor接口类型的对象 ; 3、通过SharedPreferences.Editor接口提供的 putXxx (...)方法对SharedPreferences进行更新; 4、调用SharedPreferences.Editor的 commit ()方法,将更新提交到SharedPreferences中。 clear ()方法,清空已有的所有共享参数,但不清除editor里面的数据(在commit()之后能写出去)       5、调用SharedPreferences的getXxx(String key,Xxx defaultValue)方法获取指定key的value SharedPreferences的其他常用方法:     boolean contains(String key)判断是否包含指定键的数据     Map<String,?> getAll()获取所有的键值对, 需要对象造型: Map<String,Object> map = (Map<String,Object>)sp.getAll(); 核心代码: 核心代码: public void click(View v) { if (v.getId() == R.id.bt_save) {// 保存共享参数 //要保存,必须先获取Editor对象 Editor editor = sp.edit(); // editor.putString("name", et_name.getText().toString()); // editor.putString("phone", et_phone.getText().toString()); editor.putString("test", "aaaaaaaaa"); editor.clear();//清空已有的所有共享参数,再把editor里面的数据写出去 editor.commit();//提交 Toast.makeText(this, "保存成功!", 0).show(); } else { // 读取共享参数 // String name = sp.getString("name", "默认 值-无名氏"); // String phone = sp.getString("phone", "000000"); // tv_showData.setText("name:"+name+",phone:"+phone); Map<String,?> map = sp.getAll(); Set<String> keys = map.keySet(); StringBuilder sb = new StringBuilder(); for(String aKey :keys){ Object obj = map.get(aKey); sb.append(aKey).append("=").append(obj).append('\t'); } tv_showData.setText(sb); } } (四)、保存之后的SharedPreferences数据文件:         SharedPreferences数据总是以xml格式保存在: /data/data/包名/shared_prefs /{文件名}; Cd D:\workspace\sdk\platform-tools------------adb所在的目录 adb shell cd  /data/data/包名/shared_prefs ls 查看所有的目录 cat person.xml 文件格式如下: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map>     <string name="pwd">123456</string>     <string name="username">xiangjun</string>     <int  name="age">20</int> </map> ------------------------------------------------------------------ 内部存储Internal Storage 文件存储路径: /data/data/包名/files/{文件名} Context的实例方法(Activity中继承过来了):  FileOutputStream  openFileOutput  (String filename, int mode)//用追加或覆盖的模式, 获得文件输出流, 可以写出到指定文件名的文件   mode的取值:   Context.MODE_APPEND追加模式,不写就是覆盖模式   Context.MODE_PRIVATE        中间可以用 | 或者 + 来连接 十进制12===>二进制00000000000001100 十进制5  ===>二进制00000000000000101 int k = 12&5;   //4 int m = 12|5;   //13 i:二进制00000000000001000 j:二进制00000000000000100 int k = i  | j;//12 int m = i+j;//12   Context的实例方法:  FileInputStream  openFileInput  (String filename) 该方法应写在事件处理方法里面  String[]  fileList ()列出所有的文件名数组  boolean  deleteFile (String filename)删除指定文件名的文件 [ 案例:] 点击按钮A从UI上获取用户名和手机号,保存到内部存储的文件中; 点击按钮B从内部存储中取出显示在文本框中   ---------------------------------------------------- External Storage之SDCard操作: (一)、引入: 毕竟手机内置存储空间很有限, 内存卡中可能空间不够,为了更好地存储应用程序的大文件数据,需要读写SD卡上的文件。SD卡大大扩充了手机的存储能力。   (二)、读写SD卡的步骤: 1、先判断手机是否有sd卡:      调用 Environment 的静态方法 String getExternalStorage State ()方法判断手机是否插上sdcard。得到的结果可能有: Environment. MEDIA_MOUNTED 介质已加载完 Environment.MEDIA_MOUNTED_READ_ONLY 介质已加载完,但是只读状态 Environment.MEDIA_CHECKING 正在检测介质 Environment.MEDIA_UNKNOWN  介质未知 Environment.MEDIA_UNMOUNTED 介质已卸载 2、获取sdcard的路径;         调用 Environment 静态方法String getExternalStorage Directory ()方法来获取外部存储器的目录。 3、此外还可以获取SDCard可用磁盘空间的大小(借助 StatFs 类来实现); 4、清单文件中设置读写sdcard的权限;   <uses-permission android:name="android.permission. MOUNT_UNMOUNT_FILESYSTEMS "/>   允许挂载和反挂载文件系统可移动存储   <uses-permission android:name="android.permission. WRITE_EXTERNAL_STORAGE "/>   <uses-permission android:name="android.permission. READ_EXTERNAL_STORAGE " /> 5、执行读写操作(基本IO流操作)。   (三)、封装SDCard的工具类:SDCardHelper类 判断sdcard是否挂载 boolean isSDCardMounted()     getExternalStorageState()     Environment.MEDIA_MOUNTED 获取sdcard绝对物理路径 String getSDCardPath()     getExternalStorageDirectory() 获取sdcard的全部的空间大小。返回MB字节 long getSDCardSize()        new StatFs( getSDCardPath ());     sf.getBlockSize();//获取每块的大小      sf. getBlockCount();//获取总块数 获取sdcard的剩余空间的大小。返回MB字节 long getSDCardFreeSize()      sf. getFreeBlocks();//获取空闲的块数 获取SD卡的可用空间大小,返回MB long getSDCardAvailableSize()      sf. getAvailableBlocks();//获取可用空间的大小 将文件(byte[])保存进sdcard指定的路径下  dir:指定的路径 boolean saveFileToSDCard(byte[] data, String dir,String filename)   已知文件的 绝对路径 ,从sdcard中获取到该文件,返回byte[].     byte[] loadFileFromSDCard(String filepath) public class SDCardHelper { private static String TAG = "SDCardHelper"; /** * 判断sdcard是否挂载 */ public static boolean isSDCardMounted() { return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); } /** * 获取sdcard绝对物理路径 得到的格式为 /storage/sdcard 后面没有斜线 */ public static String getSDCardPath() { if (isSDCardMounted()) { return Environment.getExternalStorageDirectory().getAbsolutePath(); } else { return null; } } /** * 获取sdcard的全部的空间大小。返回MB字节 */ public static long getSDCardSize() { if (isSDCardMounted()) { StatFs fs = new StatFs(getSDCardPath()); // 因为带有Long结尾的替代方法需要API 18以上的SDK才能支持,所以,暂时使用旧的 long size = fs.getBlockSize(); long count = fs.getBlockCount();// 获取总块数 return size * count / 1024 / 1024; } return 0; } /** * 获取sdcard的剩余空间的大小。返回MB字节 */ public static long getSDCardFreeSize() { if (isSDCardMounted()) { StatFs fs = new StatFs(getSDCardPath()); long size = fs.getBlockSize(); long count = fs.getFreeBlocks();// 获取空闲的块数 return size * count / 1024 / 1024; } return 0; } /** * 获取SD卡的可用空间大小,返回MB * * @return */ public static long getSDCardAvailableSize() { if (isSDCardMounted()) { StatFs fs = new StatFs(getSDCardPath()); int count = fs.getAvailableBlocks();// 获取可用空间的大小 int size = fs.getBlockSize(); return count * size / 1024 / 1024; } return 0; } /** * 将文件(byte[])保存进sdcard指定的路径下 dir:指定的路径 */ public static boolean saveFileToSDCard(byte[] data, String dir, String filename) { BufferedOutputStream bos = null; if (isSDCardMounted()) { Log.i(TAG, "==isSDCardMounted==TRUE"); File file = new File(getSDCardPath() + File.separator + dir); Log.i(TAG, "==file:" + file.toString() + file.exists()); if (!file.exists()) { boolean flags = file.mkdirs(); Log.i(TAG, "==创建文件夹:" + flags); } try { bos = new BufferedOutputStream(new FileOutputStream(new File(file, filename))); bos.write(data, 0, data.length); bos.flush(); return true; } catch (Exception e) { e.printStackTrace(); } finally { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 已知文件的绝对路径,从sdcard中获取到该文件,返回byte[] */ public static byte[] loadFileFromSDCard(String filepath) { BufferedInputStream bis = null; ByteArrayOutputStream baos = null; if (isSDCardMounted()) { File file = new File(filepath); if (file.exists()) { try { baos = new ByteArrayOutputStream(); bis = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[1024 * 8]; int c = 0; while ((c = bis.read(buffer)) != -1) { baos.write(buffer, 0, c); baos.flush(); } return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (bis != null) { bis.close(); baos.close(); } } catch (IOException e) { e.printStackTrace(); } } } } return null; } }
    转载请注明原文地址: https://ju.6miu.com/read-675045.html

    最新回复(0)