数据存储——Android存储目录
在android系统中,应用程序持久化保存数据的方式有:(持久化保存:如果不清除会一直存在,在手机死机,重启时数据不会丢失)
·SQLite
android 系统提供了多种存储应用程序的数据的方式
开发人员应该根据以下原则进行选取:
·数据是否需要私有化
·数据的类型及其存储形式
·数据量的大小
·数据是否需要共享给其他应用程序
·其它
日志文件可以用文本文件
像应用的配置信息可能使用xml文件存储比较合适
对应数据量比较大,数据类型明确,数据之间的关联比较复杂的,需要共享给其他应用程序情况可以采用数据库存储
使用内部存储:
·当应用程序部署到设备上之后,设备上会存在路径为/data/data/应用程序 包名的文件夹,使用内部存储的方式写入的文件默认保存在该文件夹的
files 文件夹中;
·在/data/data/应用程序包名文件夹下的文件,子级文件夹是应用程序私有 的
·如果应用程序被卸载,内部存储的文件会一并移除
·在Android中,使用一般的I/O操作模式即可写实现内部存储,即使用字节流或字符流
·调用openFieInput()方法即可用获得FileInputStream对象,而调用 openFileOutput()方法则可以获得FileOutputStream对象;
在I/O相关操作中,可能需要确定读写模式,使用Context类定义的常量即可,相关的常量值有:
·MODE_PRIVATE:私有,在创建文件时即被设置为应用程序私有;写入的内容会覆盖原文件的内容,
·MODE_APPEND:添加模式
·MODE_WORLD_READABLE:全设备可读
·MODE_WORLD_WRIREABLE:全设备可写
存储目录:
存储设备:
·RAM(随机存储器,相当于电脑的内存条是cpu与其他设备交换的桥梁)
·ROM(相当于计算机的硬盘)
·SD扩展卡(相当于计算机的u盘,移动硬盘)
内部存储的相关方法
·在ContextWrapper类中定义了一系列方法,实现访问,管理内部存储相关的 文件,文件夹,常用的方法有:
·getFilesDir()访问/data/data/应用包名/files/文件夹,该方法的返回值是File类型的数据
·getDir()访问/data/data/应用包名/文件夹下指定name的文件夹,该方法的返回值是 File类型的数据
·如果需要访问的文件夹不存在,则会创建该文件夹;
·为了避免和系统可能会创建的文件夹发生冲突,开发人员自定义的文件夹会 自动被android系统加上app_前缀,但是在使用过程中开发人员可以不考虑
·fileList()
获取私有文件列表,该方法的返回值为String[]类型数据
·deleteFile()
删除指定的私有文件,该方法的返回值为boolean,表示是否成功删除了文件
方法签名:public boolean deleteFile(String name);
外部存储简介
·每个兼容Android的设备都支持一个共享的外部存储空间,它可能表现为SD 卡,也可能为ROM中非应用程序私有的空间;
·一般外部存储用于保存于应用程序没有必然关系的文件,例如用户自行下载 的音乐,图片,电影等;
·外部存储的空间是设备上所有应用程序均具有读写权限的空间,不适合保存 私有数据
sd卡是Android设备中的可选扩展存储设备,绝大部分Android设备支持用户自行扩展
挂载外部存储:
在android系统中,外不存储设备需要“挂载(mount)”之后才可以使用
在默认情况下,已正确使用的外部存储设备是“已挂载”状态;
在对外部存储设备进行写入操作时,需要添加如下权限:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Environment的静态方法
Environmentl类提供了一系列静态方法用于访问,管理外部存储设备,
常用的方法有:
·getExternalStorageState();
获取外部存储的挂载状态,该方法返回String类型数据
当SD卡未正确插入,被色定为只读,卡片破损,正在以USB形式连接PC等均会 导致其不可用,因此在使用前应该检查状态
可使用Enviroment类的MEDIA_MOUNTED常量对比该方法的返回值
·getExternalStorageDirectory()
获取sdcard的根目录,该方法返回值为File类型的数据;
不同版本的设备中sdcard目录的位置可能有所不同,但是不影响该方法的使用
·getExternalStoragePublicDirectory()
获取外部存储下指定的目录,该方法返回值为File类型数据
该方法的参数不可为空,且应该使用Environment中的静态常量作为参数值
Environment 的静态常量
android 系统默认在外部存储下定义了Music,Pictures等文件夹,且希望开发人员有规则的使用这些文件夹,在Environment中存在以下常量表示这些
文件夹的名称:
Environment.DIRECTORY_MUSIC;音乐
Environment.DIRECTORY_RINGTONES;铃声
Environment.DIRECTORY_ALARMS;闹钟
Environment.DIRECTORY_NOTIFICATIONS;通知
Environment.DIRECTORY_PICTURES;图片
Environment.DIRECTORY_MOVIES;电影
Environment.DIRECTORY_DOWNLOADS;下载
Environment.DIRECTORY_DCIM;照相机
外部存储:
使用外部存储保存数据:
·直接使用JAVA中I/O操作即可使用外部存储保护数据
·例如在创建文件的FileInputStream,FielOutputStream对象,或FileReader,
FileWriter对象,实现读写文件的操作,亦可使用其它流对现有的流进行包装以提高性能
关于媒体扫描:
·在Android系统中,媒体文件(图片,音乐,电影等)即使被添加到存储器 中,也不会被系统实时获取
·原生的Android系统自带应用程序可浏览图片,播放电影或音乐但并非这 些文件实时添加后,对应的应用程序即知晓文件已存在;
· Android系统使用数据库保存设备上的媒体文件信息,而各应用程序则通过 访问相关的数据库获取媒体文件的列表等信息
·在一般情况下,开机时系统会发出扫描媒体的广播,则对应的处理程序收到 该广播后将执行扫描
·开发人员可以调用
callback)
数据存储-Android存储目录
04.缓存文件夹
当需要缓存一部分数据,但并非永久性保存这些数据时,即可使用缓存。
·缓存的本质依然是使用文件保存数据,区别在于:缓存的文件可能会被系统 自动清除,或开发人员应该设定某些逻辑进行清除,比如定期清除或达到限定值
内部缓存:
·调用ContextWrapper类定义的getCacheDir()方法即可获取内部缓存文件夹 ,该方法返回File类型数据
·该方法返回的File对象对应/data/data/应用程序包名/cache/文件夹;
·cache文件夹是应用程序的缓存文件夹,当设备的内部存储空间不足时
系统会自动清理缓存文件夹以释放空间,但一般推荐开发人员自行维护缓存文件;
·当应用程序被卸载时,缓存的文件也会被清除;
外部缓存:
调用ContextWrapper类定义的getExternalCacheDir()可获取外部缓存根目录的File的对象
·为了避免各个应用程序冲突,外部缓存文件夹路径为sdcard下的Android/data/应用程序包名/cachea/文件夹
·该方法签名
public File getExternalCachDir()
·外部缓存与内部缓存的区别:
·Android 系统并不会实时监控外部缓存的空间使用情况,因此不会自动的
删除这些缓存文件,开发人员应该及时的手动清除不必要的文件,并把缓存文 件夹的使用空间控制在一个合理的范围内
·外部缓存并不是任何时候都可以用的
·外部存储并不具备安全性,因为任何应用程序都可以访问这些文件
最后用一个案例实践一下
(别忘了导入文件操作权限)
在android系统中,应用程序持久化保存数据的方式有:(持久化保存:如果不清除会一直存在,在手机死机,重启时数据不会丢失)
存储方式:
.文件存储
·SharedPreferences·SQLite
·网络
android 系统提供了多种存储应用程序的数据的方式
开发人员应该根据以下原则进行选取:
·数据是否需要私有化
·数据的类型及其存储形式
·数据量的大小
·数据是否需要共享给其他应用程序
·其它
日志文件可以用文本文件
像应用的配置信息可能使用xml文件存储比较合适
对应数据量比较大,数据类型明确,数据之间的关联比较复杂的,需要共享给其他应用程序情况可以采用数据库存储
使用内部存储:
·当应用程序部署到设备上之后,设备上会存在路径为/data/data/应用程序 包名的文件夹,使用内部存储的方式写入的文件默认保存在该文件夹的
files 文件夹中;
·在/data/data/应用程序包名文件夹下的文件,子级文件夹是应用程序私有 的
·如果应用程序被卸载,内部存储的文件会一并移除
·在Android中,使用一般的I/O操作模式即可写实现内部存储,即使用字节流或字符流
·调用openFieInput()方法即可用获得FileInputStream对象,而调用 openFileOutput()方法则可以获得FileOutputStream对象;
在I/O相关操作中,可能需要确定读写模式,使用Context类定义的常量即可,相关的常量值有:
·MODE_PRIVATE:私有,在创建文件时即被设置为应用程序私有;写入的内容会覆盖原文件的内容,
·MODE_APPEND:添加模式
·MODE_WORLD_READABLE:全设备可读
·MODE_WORLD_WRIREABLE:全设备可写
存储目录:
存储设备:
·RAM(随机存储器,相当于电脑的内存条是cpu与其他设备交换的桥梁)
·ROM(相当于计算机的硬盘)
·SD扩展卡(相当于计算机的u盘,移动硬盘)
内部存储的相关方法
·在ContextWrapper类中定义了一系列方法,实现访问,管理内部存储相关的 文件,文件夹,常用的方法有:
·getFilesDir()访问/data/data/应用包名/files/文件夹,该方法的返回值是File类型的数据
·getDir()访问/data/data/应用包名/文件夹下指定name的文件夹,该方法的返回值是 File类型的数据
·如果需要访问的文件夹不存在,则会创建该文件夹;
·为了避免和系统可能会创建的文件夹发生冲突,开发人员自定义的文件夹会 自动被android系统加上app_前缀,但是在使用过程中开发人员可以不考虑
·fileList()
获取私有文件列表,该方法的返回值为String[]类型数据
·deleteFile()
删除指定的私有文件,该方法的返回值为boolean,表示是否成功删除了文件
方法签名:public boolean deleteFile(String name);
外部存储简介
·每个兼容Android的设备都支持一个共享的外部存储空间,它可能表现为SD 卡,也可能为ROM中非应用程序私有的空间;
·一般外部存储用于保存于应用程序没有必然关系的文件,例如用户自行下载 的音乐,图片,电影等;
·外部存储的空间是设备上所有应用程序均具有读写权限的空间,不适合保存 私有数据
sd卡是Android设备中的可选扩展存储设备,绝大部分Android设备支持用户自行扩展
挂载外部存储:
在android系统中,外不存储设备需要“挂载(mount)”之后才可以使用
在默认情况下,已正确使用的外部存储设备是“已挂载”状态;
在对外部存储设备进行写入操作时,需要添加如下权限:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Environment的静态方法
Environmentl类提供了一系列静态方法用于访问,管理外部存储设备,
常用的方法有:
·getExternalStorageState();
获取外部存储的挂载状态,该方法返回String类型数据
当SD卡未正确插入,被色定为只读,卡片破损,正在以USB形式连接PC等均会 导致其不可用,因此在使用前应该检查状态
可使用Enviroment类的MEDIA_MOUNTED常量对比该方法的返回值
·getExternalStorageDirectory()
获取sdcard的根目录,该方法返回值为File类型的数据;
不同版本的设备中sdcard目录的位置可能有所不同,但是不影响该方法的使用
·getExternalStoragePublicDirectory()
获取外部存储下指定的目录,该方法返回值为File类型数据
该方法的参数不可为空,且应该使用Environment中的静态常量作为参数值
Environment 的静态常量
android 系统默认在外部存储下定义了Music,Pictures等文件夹,且希望开发人员有规则的使用这些文件夹,在Environment中存在以下常量表示这些
文件夹的名称:
Environment.DIRECTORY_MUSIC;音乐
Environment.DIRECTORY_RINGTONES;铃声
Environment.DIRECTORY_ALARMS;闹钟
Environment.DIRECTORY_NOTIFICATIONS;通知
Environment.DIRECTORY_PICTURES;图片
Environment.DIRECTORY_MOVIES;电影
Environment.DIRECTORY_DOWNLOADS;下载
Environment.DIRECTORY_DCIM;照相机
外部存储:
使用外部存储保存数据:
·直接使用JAVA中I/O操作即可使用外部存储保护数据
·例如在创建文件的FileInputStream,FielOutputStream对象,或FileReader,
FileWriter对象,实现读写文件的操作,亦可使用其它流对现有的流进行包装以提高性能
关于媒体扫描:
·在Android系统中,媒体文件(图片,音乐,电影等)即使被添加到存储器 中,也不会被系统实时获取
·原生的Android系统自带应用程序可浏览图片,播放电影或音乐但并非这 些文件实时添加后,对应的应用程序即知晓文件已存在;
· Android系统使用数据库保存设备上的媒体文件信息,而各应用程序则通过 访问相关的数据库获取媒体文件的列表等信息
·在一般情况下,开机时系统会发出扫描媒体的广播,则对应的处理程序收到 该广播后将执行扫描
·开发人员可以调用
MediaScannerConnection的scanFile()静态方法
callback)
数据存储-Android存储目录
04.缓存文件夹
当需要缓存一部分数据,但并非永久性保存这些数据时,即可使用缓存。
·缓存的本质依然是使用文件保存数据,区别在于:缓存的文件可能会被系统 自动清除,或开发人员应该设定某些逻辑进行清除,比如定期清除或达到限定值
内部缓存:
·调用ContextWrapper类定义的getCacheDir()方法即可获取内部缓存文件夹 ,该方法返回File类型数据
·该方法返回的File对象对应/data/data/应用程序包名/cache/文件夹;
·cache文件夹是应用程序的缓存文件夹,当设备的内部存储空间不足时
系统会自动清理缓存文件夹以释放空间,但一般推荐开发人员自行维护缓存文件;
·当应用程序被卸载时,缓存的文件也会被清除;
外部缓存:
调用ContextWrapper类定义的getExternalCacheDir()可获取外部缓存根目录的File的对象
·为了避免各个应用程序冲突,外部缓存文件夹路径为sdcard下的Android/data/应用程序包名/cachea/文件夹
·该方法签名
public File getExternalCachDir()
·外部缓存与内部缓存的区别:
·Android 系统并不会实时监控外部缓存的空间使用情况,因此不会自动的
删除这些缓存文件,开发人员应该及时的手动清除不必要的文件,并把缓存文 件夹的使用空间控制在一个合理的范围内
·外部缓存并不是任何时候都可以用的
·外部存储并不具备安全性,因为任何应用程序都可以访问这些文件
最后用一个案例实践一下
(别忘了导入文件操作权限)
package com.example.file_tm;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
protected static final int MESSAGE_SCAN_COMPLETED = 666;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler(new InnerHandlerCallback());
}
private class InnerHandlerCallback implements Handler.Callback{
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
if(msg.what== MESSAGE_SCAN_COMPLETED){
Toast.makeText(getApplicationContext(), "复制图片成功", 1).show();
}
return true;
}
}
/*
* 按钮方法
* */
public void copyImgFile(View v){
File src;
File dest;
FileInputStream fis;
FileOutputStream fos;
//读取sd卡中下的一张图片进行复制
src = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"image01.png");
dest = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"copofimage01.png");
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
fos.write(buffer,0,len);
}
fis.close();
fos.flush();
fos.close();
/*
* 用于扫描媒体文件
* 这个方法是一个异步方法是在子线程中运行的
*
* 该方法第二个参数是要扫描的路径数组,第三个参数是要扫描的文件类型,可以传入null
* 最后一个是扫描完成后要执行的方法,如果在给方法中Toast提示信息会报错,因为 这个方法是一个异步方法是在子线程中运行的
*
* 如果要Toast显示提示信息可以使用android的消息机制
* */
MediaScannerConnection.scanFile(this, new String[]{dest.getAbsolutePath()}, null, new OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
// TODO Auto-generated method stub
handler.sendEmptyMessage(MESSAGE_SCAN_COMPLETED);
}
});
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
xml布局文件中加入一个按钮
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="copyImgFile"
android:text="复制图片" />