一、文件管理:
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);
}