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

来源:互联网 发布:大学宿舍知乎 编辑:程序博客网 时间:2024/06/05 10:03
安卓的(持久化)存储机制:
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的静态方法 StringgetExternalStorageState()方法判断手机是否插上sdcard。得到的结果可能有:
Environment.MEDIA_MOUNTED介质已加载完
Environment.MEDIA_MOUNTED_READ_ONLY 介质已加载完,但是只读状态
Environment.MEDIA_CHECKING 正在检测介质
Environment.MEDIA_UNKNOWN  介质未知
Environment.MEDIA_UNMOUNTED 介质已卸载
2、获取sdcard的路径;
        调用Environment静态方法StringgetExternalStorageDirectory()方法来获取外部存储器的目录。
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;    }    }



0 0
原创粉丝点击