4-16 文件管理 XML解析 JSON GSON 笔记 待整理

一、文件管理:
1、内部存储操作
内部存储数据,是由本应用程序访问的私有数据,保存在/data/data/package_name/files/文件名  下
可以通过以下两个方法读取和写入私有数据:
<1>写入私有数据:
context.openFileOutput(name,mode)
name:自定义的文件名
mode:写入的模式:Context.MODE_PRIVATE 覆盖写入,Context.MODE_APPEND 追加写入
通常使用MODE_PRIVATE
由于不同的设备对手机每个应用的大小有限制,通过在几十M,所以,不建议把大量数据写入私有文件,
通常可以保存一些重要的用户数据(比如,密码等)
示例:
String info = "程序员好帅";
        try {
            BufferedOutputStream out = new BufferedOutputStream(openFileOutput("mly", Context.MODE_PRIVATE));
            out.write(info.getBytes());
            out.close();
            Toast.makeText(MainActivity.this, "write success", Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

<2>读取私入数据:
context.openFileInput(name)
name:已经存在的自定义文件名
示例:
 try {
            BufferedInputStream in = new BufferedInputStream(openFileInput("mly"));
            StringBuilder buf = new StringBuilder();
            byte[] bytes = new byte[1024*100];
            int len = -1;
            while((len=in.read(bytes))!=-1){
                buf.append(new String(bytes,0,len));
            }
            in.close();
            Toast.makeText(MainActivity.this, buf, Toast.LENGTH_SHORT).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

<3>操作raw目录的文件(原生)res/raw
raw文件中资源文件的一种,只能读取,不能写入
可以存放一些声音资源文件

1>通常使用该资源实现数据的初始化工作:
在程序第一次运行时,读取该资源数据,执行相应的操作,比如(初始化数据库数据)
public void readRAWClick(View v){
       BufferedInputStream in = new BufferedInputStream(getResources().openRawResource(R.raw.sql));
        StringBuilder buf = new StringBuilder();
        byte[] bytes = new byte[1024];
        int len = -1;
        try {
            while((len=in.read(bytes))!=-1){
                buf.append(new String(bytes,0,len));
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //读取到的SQL语句,再去执行
    }
2>实现文件的加密处理
在一个应用程序中,需要安装其它APK,通常会把这个APK文件与当前程序一起打包,在安装时同时安装这个APK,一些安全类APP可能扫描到这个而外安装的APK文件,以提醒用户,为了防止安全类应用扫描,我们会把这个APK文件进行加密处理,放到RAW资源目录中,在执行某一个操作时,读取这个加密文件,并生成(还原)APK,保存到SDCARD上,再执行安装操作
例如:
在实现支付操作时,需要安装支付插件,我们就把支付插件加密后保存在RAW目录中。

<3>asserts
存放资源文件,不会生成索引原生文件
通常在该目录下存放,网页文件、数据库数据文件、APK文件,不会受res资源的相关限制

<4>操作内部缓存目录:
系统在内存低的情况下,会自动清除缓存,但通常我们应该自己维护缓存
一般大小在1MB
Log.i("cache",getCacheDir().toString());
        try {
            //创建一个临时文件(前缀,后缀,文件目录)
            File file = File.createTempFile("mly","tmp",getCacheDir());
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bos.write("今天下雨了".getBytes());
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

<5>    外部存储(sdcard)
检查sdcard:
    public static boolean isExternalStorageWritable(){
        String state = Environment.getExternalStorageState();
        //判断是否存在外部存储设备(可写)
        if(Environment.MEDIA_MOUNTED.equals(state)){
           return true;
        }
        return false;

    }

    public static boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        //判断sdcard是否可读
        if (Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            return true;
        }
        return false;
    }

获取sdcard的根目录:
 public static String getSDCardPath(){
        return Environment.getExternalStorageDirectory().getPath();
 }
  通配符:sdcard  

获取外部私有目录(4.4)
/**
     * 获取外部存储的私有目录(4.4)
     * @param context
     * @return
     */
    public static File getExternalFilesDir(Context context){
        File file = context.getExternalFilesDir(null);
        if(file==null){
            file = new File(Environment.getExternalStorageDirectory()+EXTERNAL_FILE_DIR);
        }
        return file;
    }

    /**
     * 获取外部存储的私有缓存目录(4.4)
     * @param context
     * @return
     */
    public static File getCacheDir(Context context){
        File file = context.getExternalCacheDir();
        if(file==null){
            file = new File(Environment.getExternalStorageDirectory()+EXTERNAL_CACHE_DIR);
        }
        return file;
    }

获取sdcard的总空间大小和可用空间大小
    /**
     * 获取sdcard的可用空间大小
     * @return
     */
    public static long getFreeSpace(){
        return Environment.getExternalStorageDirectory().getFreeSpace();
    }

    /**
     * 获取sdcard的总空间大小
     * @return
     */
    public static long getTotalSpace(){
        return Environment.getExternalStorageDirectory().getTotalSpace();
    }

获取sdcard上自带的指定目录:
//图片
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
//警报声音,闹钟声音
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS)
//相机
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
//文档
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)
//下载
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
//视频
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
//音乐
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
//通知
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS)
//博客
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PODCASTS)
//铃声
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES)

注意:
在实际开发中,我们通常会使用sdcard来作为本应用程序的缓存位置,我们可以在sdcard上创建一个
属于本应用程序使用的自定义目录(通过存放一些非敏感的数据)
敏感数据一般放在sdcard上的私有目录(sdcard/Andorid/data/package_name/...下,或
应用程序下的私有目录:data/data/package_name/files/...   或/cache/...)

面试题:问Android存储数据的方式有哪些:
Shared Preferences(共享属性文件)
Internal Storage(内部存储)
External Storage(外部存储)
SQLite Databases(SQLite数据库)
Network Connection(网络)

对sdcard的读写操作必须添加权限:



二、XML解析
SAX:
基于事件驱动,顺序读取,占用内存小,不能任意访问指定节点(不灵活),速度快
适用于对内存要求高的设备使用

DOM:
基于树型结构存储,一次性把文档读入内存,占用内存较大,可以任意访问节点(灵活)
适用于在服务器端开发使用
基于DOM的实现还有:
JDOM(API使用集合)
DOM4J(整体性能较好,Hibernate就是使用Dom4j实现配置文件的解析)

PULL解析:
PULL解析的机制与SAX解析相似,都是基于事件驱动
不同的是:
SAX使用一个ContentHandler(内容处理器)来处理数据,解析器读取到相应的内容以回调
ContentHandler的相应方法的方式来处理。
而PULL是使用事件类型常量的标记的方式来处理数据。

使用PULL的步骤:
<1>创建一个PULL解析器对象:
XmlPullParser xmlPullParser = Xml.newPullParser();
<2>设置要解析的数据源
InputStream in = getResources().openRawResource(R.raw.person);
xmlPullParser.setInput(in,"utf-8");
<3>获取事件类型
int eventType = xmlPullParser.getEventType();
<4>通过循环来处理不同的事件类型,结束条件为解析到文档的末尾
while(eventType!=XmlPullParser.END_DOCUMENT){
    //.....
    eventType = xmlPullParser.next();
}
示例:

    private ArrayList  parseXML() {
//        InputStream in = Xml.parse();  sax解析
        InputStream in = getResources().openRawResource(R.raw.person);
        //创建PULL解析器对象
        XmlPullParser xmlPullParser = Xml.newPullParser();
        ArrayList persons = new ArrayList();
        Person p = null;
        try {
            //设置要解析的数据源
            xmlPullParser.setInput(in,"utf-8");
            int eventType = xmlPullParser.getEventType();
            while(eventType!=XmlPullParser.END_DOCUMENT){
                try {
                    switch (eventType){
                        case XmlPullParser.START_TAG:
                            String tag = xmlPullParser.getName();
                            p = getPerson(xmlPullParser, p, tag);
                            break;
                        case XmlPullParser.END_TAG:
                            if("person".equals(xmlPullParser.getName())){
                                persons.add(p);
                            }
                            break;
                    }
                    eventType = xmlPullParser.next();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }

        return persons;
    }

    private Person getPerson(XmlPullParser xmlPullParser, Person p, String tag) throws XmlPullParserException, IOException {
        if("person".equals(tag)){
            p = new Person();
            p.setPersonid(xmlPullParser.getAttributeValue(xmlPullParser.getNamespace(),"personid"));
        }else if("name".equals(tag)){
            p.setName(xmlPullParser.nextText());
        } else if("age".equals(tag)){
            p.setAge(Integer.parseInt(xmlPullParser.nextText()));
        } else if("sex".equals(tag)){
            p.setSex(xmlPullParser.nextText());
        } else if("tel".equals(tag)){
            p.setTel(xmlPullParser.nextText());
        }
        return p;
    }

使用PULL解析天气数据
http://ws.webxml.com.cn/WebServices/WeatherWS.asmx/getWeather?theCityCode=北京

三、JSON解析
JSON是除XML外的另一种数据交换格式,通常不同程序或与服务器之间传递数据
android 3.0 api11 后提供JsonReader工具类用于解析JSON

JsonReader jsonReader new JsonReader(Reader)

1、有一个json数据:
[
  {
    "firstName": "DAI",
    "lastName": "BOBO",
    "email": "[email protected]"
  },
  {
    "firstName": "XIN",
    "lastName": "JIANJIAN",
    "email": "[email protected]"
  }
]
例:
    private ArrayList parseJSON() {
        InputStream in = getResources().openRawResource(R.raw.user);
        JsonReader jsonReader = new JsonReader(new InputStreamReader(in));
        ArrayList list = new ArrayList<>();
        try {
            jsonReader.beginArray();
            while (jsonReader.hasNext()){
                User user = getUser(jsonReader);
                list.add(user);
            }
            jsonReader.endArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

    @NonNull
    private User getUser(JsonReader jsonReader) throws IOException {
        jsonReader.beginObject();
        User user = new User();
        while(jsonReader.hasNext()){
            String name = jsonReader.nextName();
            if("firstName".equals(name)){
                user.setFirstName(jsonReader.nextString());
            }else if("lastName".equals(name)){
                user.setLastName(jsonReader.nextString());
            }else if("email".equals(name)){
                user.setEmail(jsonReader.nextString());
            }
        }
        jsonReader.endObject();
        return user;
    }

2、jsonReader工具的常用方法:

beginArray()    --开始解析数组
endArray()        --结束解析数组
beginObject()    --开始解析对象
endObject()    --结束解析对象
hasNext()        --判断是否有下一个元素(数组、对象、元素)
nextBoolean()    --获取当前元素的boolean值
nextDouble()    --获取当前元素的double值
nextInt()            --获取当前元素的int值
nextLong()        --获取当前元素的long值
nextNull()        --获取当前元素的null值
nextString()    --获取当前元素的字符串值 (包含其它类型)
peek()                --获取当前元素的类型
skipValue()        --跳过当前元素
nextName()    --获取当前元素的名称(key值)
close()                --结束解析时关闭

3、生成一组JSON数据:
使用JSONArray和JSONObject

示例:
public void createJSONClick(View view){
        ArrayList users = new ArrayList<>();
        users.add(new User("hong","cai","[email protected]"));
        users.add(new User("da","lei","[email protected]"));
        users.add(new User("zhang","wei","[email protected]"));
        createJSON(users);
}

private String createJSON(ArrayList users) {
        JSONArray array = new JSONArray();
        for (User user : users) {
            JSONObject obj = new JSONObject();
            try {
                obj.put("firstName",user.getFirstName());
                obj.put("lastName",user.getLastName());
                obj.put("email",user.getEmail());
            } catch (JSONException e) {
                e.printStackTrace();
            }
            array.put(obj);
        }
        return array.toString();
    }

4、使用Google官方JSON组件(GSON)
GSON是由Google提供的一个用于解析JSON的组件,在很多项目开发中都使用GSON
我们在使用GSON时只需要把相应的JAR包添加到工程的libs目录下,并添加到工程的类库中即可。
下载地址:http://mvnrepository.com/artifact/com.google.code.gson/gson

    //使用GSON
    private void gson() {
        Gson gson = new Gson();
        //把JSON数据转换成JAVA对象
        String json = "{\"firstName\": \"DAI\",\"lastName\": \"BOBO\",\"email\": \"[email protected]\"}";
        User user = gson.fromJson(json,User.class);
        Log.i("JSON",user.toString());

        //把JSON数组转换成JAVA对象集合
        String json2 = "[{\"firstName\": \"DAI\",\"lastName\": \"BOBO\",\"email\": \"[email protected]\"}," +
                "{\"firstName\": \"hong\",\"lastName\": \"cai\",\"email\": \"[email protected]\"}]";
        //new TypeToken>(){}.getType()  
        //指定使用类型存储JSON转换的对象
        ArrayList list = gson.fromJson(json2, new TypeToken>(){}.getType());
        for (User user1 : list) {
            Log.i("JSON",user1.toString());
        }

        //把对象转换成JSON数据
        User user3 = new User("hong","cai","[email protected]");
        String json4 = gson.toJson(user3);
        Log.i("JSON",json4);

        //把一组对象转换成JSON数组
        ArrayList users = new ArrayList<>();
        users.add(new User("hong","cai","[email protected]"));
        users.add(new User("da","lei","[email protected]"));
        users.add(new User("zhang","wei","[email protected]"));
        String json5 = gson.toJson(user);
        Log.i("JSON",json5);
    }














你可能感兴趣的:(笔记参考)