安卓四大存储之文件存储
四大存储方式,其实是五大,因为网络云存储也已经普及得挺快的。不过这里先谈谈文件存储,也看过很多的博文,和一些零星的观点。但是网上的资料真的是找shi爹了。所以还是自己写点总结。
关于存储的问题
因为手机的ROM一般都是固定的,所以我们应该珍惜它的容量。 Android本身来讲是一个Linux操作系统,所以它的内部存储空间,对于应用程序和用户来讲就是“/data/data"目录。它与其他的(外部的存储)相比肯定是有着比较稳定,存储方便,操作简单,更加安全(因为可以控制访问权限)等优点。而它唯一的缺点就是它比较有限,比较可贵。虽然,可以非常容易的知道程序本身的数据所在路径,所有的应用程序的数据路径都是“/data/data/app-package-name/”,所有的程序用到的数据,比如libs库,SharedPreferences都是存放在这个路径下面。但我们在使用的时候最好不要,或是千万不要直接引用这个路径。
使用内部存储主要有二个方式,一个是文件操作,一个是文件夹操作。无论哪种方式,Context中都提供了相应的函数来支持,使用Context不但操作简单方便,最重要的是Context会帮助我们管理这些文件,也可以方便帮助我们控制文件的访问权限。先来系统的说下Context中关于文件和文件夹操作的函数有哪些。
再来谈谈手机外部存储空间,与内部存储空间相对,外部存储空间是指手机出厂的时候不存在,用户在使用时候可以自由添加的外部存储介质比如TS卡,SD卡等闪存储介质。这些闪存介质由最初的空间小价格贵,到现在的大容量价格便宜,所以几乎每个支持外部存储的手机上面都有大容量(大于等于2G)的闪存卡。
Android也是不例外,它完全支持外部存储介质。其实更确切的说,它是要依赖于外部存储卡的,因为对于Android系统,如果没有外部存储卡,很多的系统应用无法使用,比如多媒体相关的应用程序无法使用。虽然Android很依赖,但是外部存储卡也有它自身的特点,它最大的优点就是存储空间大,基本上你可无限制的使用,也不怎么担心去清除数据。就目前来看,很多程序都在使用外部存储卡,但很少有程序去主动清理数据,所以无论你的SD卡有多大,它的可用空间却越来越少。与内部存储不同的是,当程序卸载时,它在外部存储所创建的文件数据是不会被清除的。所以清理外部存储空间的责任丢给了用户自己,每隔一段时间就去查看下SD卡,发现无用数据立马删除。外部存储的缺点就是不是很稳定,对于Android手机来讲可以说,很不稳定,本身闪存介质就容易出问题,SD卡处于不能正常使用的状态十分多。
如果你使用API 8(Android 2.2)或者更高,那么SDK中又多了几个操作外部存储文件和路径的接口,文档中也建议开始者更加规范的使用SD卡。比如,创建相应的目录去存储相应的数据,Music,Picture,Video等。应用程序目录也变成了"/Android/data/package-name/data"。具体的使用可以参考文档,这里不重复。当然,就像编程规范一样,这里只是规范,你完全可以不遵守它,但出于可读性和可移植性,还是建议按照文档建议的去做。
同时感谢博文: http://ipjmc.iteye.com/blog/1447097
下面总结一下使用时应该注意的一些和外部存储的特点:
a. 外部存储卡不是随时想用就能够用的,所以一定要记得在使用之前检查它的可用性
b. 存储在外部存储卡上的数据是所有应用程序都可见,用户也可见(使用FileManager),所以安全性不是很好,虽然文档声称可以在外部存储卡上写程序私有数据,但貌似没用,用FileManager仍然可以删除或编辑文件(Market上面的FileManager功能都十分的强大,能让用户看到SD卡中的所有文件,和操作能看到的文件)。
c. Android手机支持把外部存储卡Mount至PC做为U盘,当连接数据线时,这时SD卡变成了U盘连接到了另外的操作系统中。什么意思,就是在Android当中虽然有的文件属性(隐藏,私有等),到了PC上就不一定管用了,用户在PC上可以随意操作文件(这就是第二点中所提及的)。
d. 如果使用外部存储卡保存数据,一定要额外做好异常处理:外部存储卡不可用时把数据存入哪里;可用的时候再怎么同步数据(这是比较头疼的地方,可行的做法就是当SD卡不可用时不准用户写数据,但这用户体验又不是很好,但如你所知,很多应用都这么干);你的数据被破坏了。当然常见的异常也要考虑,比如空间满了,无法写入,磁盘坏道等。
我们还可以看一下常见的文件目录:
别忘了权限
<!-- 在SD卡中创建和删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 往SD卡写入数据的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
本章总结从ROM对RAM,SDCARD对RAM的操作:
我喜欢这个官方规范
/mnt/sdcard/Android/data/zy.zh.filedemo/cache
该目录在程序卸载后会自动删除
/*****
* 文件操作类
*
* @author
*
*/
public class FileService {
/**
* 上下文对象
*/
private Context context;
/**
* SD卡目录
*/
private File fileSD;
/**
* 检测SD卡存在,并且可写
*/
public boolean existSDCard() {
return (Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED));
}
// /mnt/sdcard/Android/data/zy.zh.filedemo/cache
// 该目录在程序卸载后会自动删除
public FileService(Context context) {
super();
this.context = context;
// File file = new File(Environment.getExternalStorageDirectory(),
// "Android");
// file = new File(file, "data");
// file = new File(file,context.getPackageName());
// fileSD = new File(file, "cache");
// 以上注释也是可以用的
fileSD = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/" + context.getPackageName() + "/cache");
if (!fileSD.exists()) {
if (!fileSD.mkdirs()) {
return;
}
}
try {
new File(fileSD, ",nomedia").createNewFile();// 建立文件
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 保存文件至手机自带的存储空间ROM中
*/
@SuppressWarnings("static-access")
public void save(String filename, String fileContent) throws Exception {
FileOutputStream fos = context.openFileOutput(filename,
context.MODE_PRIVATE); // 默认保存在手机自带的存储空间
fos.write(fileContent.getBytes("UTF-8"));
fos.close();
}
/**
* 读取文件内容,从ROM空间中读取
*/
public String read(String filename) throws Exception {
FileInputStream fis = context.openFileInput(filename);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
// 将内容读到buffer中,读到末尾为-1
while ((len = fis.read(buffer)) != -1) {
// 本例子将每次读到字节数组(buffer变量)内容写到内存缓冲区中,起到保存每次内容的作用
outStream.write(buffer, 0, len);
}
// 取内存中保存的数据
byte[] data = outStream.toByteArray();
fis.close();
String result = new String(data, "UTF-8");
return result;
}
/**
* 保存文件至SD卡
*/
public void saveInSDCard(String filename, String fileContent)
throws Exception {
File file = new File(fileSD, filename);
FileOutputStream fos = new FileOutputStream(file);
fos.write(fileContent.getBytes("UTF-8"));
fos.close();
}
/**
* 读取SD卡中文本文件
*/
public String readSDFile(String fileName) {
StringBuffer sb = new StringBuffer();
File file = new File(fileSD, fileName);
try {
FileInputStream fis = new FileInputStream(file);
int c;
while ((c = fis.read()) != -1) {
sb.append((char) c);
}
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
/**
* 删除rom中的文件
*/
public void delFileInRom(String fielName) {
File file = new File(context.getFilesDir(), fielName);
if (file.exists()) {
boolean result = file.delete();
Log.i(getClass().getSimpleName(), "删除 result=" + file.getPath()
+ "=" + result);
}
}
/**
* 删除SD卡的文件
*/
public void delFileInSDcard(String filename) {
File file = new File(fileSD, filename);
if (file.exists()) {
boolean result = file.delete();
Log.i(getClass().getSimpleName(), "删除 result=s" + file.getPath()
+ "=" + result);
}
}
public void testDir() {
LOGI("getFilesDir()=" + context.getFilesDir().getPath());
LOGI("getCacheDir()=" + context.getCacheDir().getPath());
LOGI("getExternalCacheDir()=" + context.getExternalCacheDir().getPath());
LOGI("getDataDirectory()="+Environment.getDataDirectory().getPath());
}
private void LOGI(String text) {
Log.i(getClass().getSimpleName(), text);
}
}
输出系统路径为:
转载请联系作者并注明出处:http://blog.csdn.net/dreamintheworld/article/details/38542417