今天有人问我“外部存储是单指sd卡么?”“手机内部存储是看不到的, 对吧?”(其他程序是否可访问获取)。存取文件,开发中大家都会用,功能都能实现。但很多都说不清楚。诸如,设置里面应用清除数据、清除缓存数据,都是清除的什么数据;各个安卓系统版本不同,外部存储路径不同,等等。关于文件存取相关的东西比较多,做为开发是需要梳理清楚的。
内存
内存与PC的内存是一样的,是用来运行程序,不能用来永久存储数据,手机一旦关机,在内存中的所有数据都将会丢失,内存也是现在人类制造的所有电子设备所必需拥有的。
内部存储
内部存储是内存吗?不是。内部存储是用于存储Andoid 设备的操作系统和应用程序的存储介质。也就是说,Android设备中的Android系统和应用程序(APK文件)都是存在内部存储区的。例如手机的/system/目录、/data/目录等。是可以永久保存数据的。
将文件存储于内部存储中,文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。从技术上来讲如果你在创建内部存储文件的时候将文件属性设置成可读,其他app能够访问自己应用的数据,前提是他知道你这个应用的包名,如果一个文件的属性是私有(private),那么即使知道包名其他应用也无法访问。
内部存储空间十分有限,我们要尽量避免使用。
Shared Preferences和SQLite数据库都是存储在内部存储空间上的。内部存储一般用Context来获取和操作。
访问内部存储的API方法:
1、Environment.getDataDirectory()
2、getFilesDir().getAbsolutePath()
3、getCacheDir().getAbsolutePath()
4、getDir(“myFile”, MODE_PRIVATE).getAbsolutePath()
外部存储
pc机(电脑)自带的硬盘算是内部存储,U盘或者移动硬盘就是外部存储。
安卓4.4(API19)以前的手机,内置存储(机身存储:手机自身带的存储卡)就是内部存储,外部存储就是扩展的SD卡。
但从4.4的系统开始,很多的中高端机器都将自己的机身存储扩展到了8G以上、16G、32G等。4.4系统及以上的手机将机身存储存储(手机自身带的存储叫做机身存储)在概念上分成了”内部存储internal” 和”外部存储external” 两部分。如果4.4系统及以上的手机插SD卡,SD卡也是外部存储。4.4系统及以上的手机的外部存储可能包含两部分,一是机身存储的外部存储部分,一是SD卡部分。在4.4以后的系统中,API提供了这样一个方法来遍历手机的外部存储路径:
File[] files;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
files = getExternalFilesDirs(Environment.MEDIA_MOUNTED);
for(File file:files){
Log.e(“main”,file);
}
}
访问外部存储的API方法:
1、Environment.getExternalStorageDirectory().getAbsolutePath()
2、Environment.getExternalStoragePublicDirectory(“”).getAbsolutePath()
3、getExternalFilesDir(“”).getAbsolutePath()
4、getExternalCacheDir().getAbsolutePath()
存储路径
不同的Android版本,存在一些差异。
基于荣耀7的(系统版本6.0)路径:
1、Environment.getDataDirectory() = /data
这个方法是获取内部存储的根路径
2、getFilesDir().getAbsolutePath() = /data/user/0/packname/files
这个方法是获取某个应用在内部存储中的files路径
3、getCacheDir().getAbsolutePath() = /data/user/0/packname/cache
这个方法是获取某个应用在内部存储中的cache路径
4、getDir(“myFile”, MODE_PRIVATE).getAbsolutePath() = /data/user/0/packname/app_myFile
这个方法是获取某个应用在内部存储中的自定义路径
方法2,3,4的路径中都带有包名,说明他们是属于某个应用
…………………………………………………………………………………………
5、Environment.getExternalStorageDirectory().getAbsolutePath() = /storage/emulated/0
这个方法是获取外部存储的根路径
6、Environment.getExternalStoragePublicDirectory(“”).getAbsolutePath() = /storage/emulated/0
这个方法是获取外部存储的根路径
7、getExternalFilesDir(“”).getAbsolutePath() = /storage/emulated/0/Android/data/packname/files
这个方法是获取某个应用在外部存储中的files路径
8、getExternalCacheDir().getAbsolutePath() = /storage/emulated/0/Android/data/packname/cache
这个方法是获取某个应用在外部存储中的cache路径
注意:其中方法7和方法8如果在4.4以前的系统中getExternalFilesDir(“”)和getExternalCacheDir()将返回null,即4.4以前的系统没插SD卡的话,就没有外部存储;而4.4及以后的系统外部存储包括两部分,getExternalFilesDir(“”)和getExternalCacheDir()获取的是机身存储的外部存储部分,即4.4及以后的系统你不插SD卡,它也有外部存储,既然getExternalFilesDir(“”)和getExternalCacheDir()获取的是机身存储的外部存储部分,那么怎么获取SD卡的存储路径呢,通过上面提到的getExternalFilesDirs(Environment.MEDIA_MOUNTED)方法来获取。
…………………………………………………………………………………………
Environment.getDownloadCacheDirectory() = /cache
Environment.getRootDirectory() = /system
这两个方法,每个版本的android系统都一样
…………………………………………………………………………………………
/data目录下的文件物理上存放在我们通常所说的内部存储里面
/storage目录下的文件物理上存放在我们通常所说的外部存储里面 ,API方法都带了一个External
/system用于存放系统文件,/cache用于存放一些缓存文件,物理上它们也是存放在内部存储里面的
设置里面应用清除数据、清除缓存数据,都是清除的什么数据
1.清除缓存:应用程序在运行过程中需要经过很多过程,如读入程序,计算,输入输出等等,这些过程中会产生很多的数据,它们在内存中,以供程序运行时调用。清除缓存清除的是APP运行过程中所产生的临时数据。
- 清除数据:清除数据是真正的删除了我们保存在文件中的数据(永久性数据),当我们在设置里面清除了某个应用的数据,那么/data/user/0/packname/和/storage/emulated/0/Android/data/packname/下的文件里面的数据会全部删除,包括cache,files,lib,shared_prefs等等。
内部存储本身就比较小,而且已经存储了一些系统的文件,我们因尽量不要使用。一般做法:
public static String getFilePath(Context context,String dir) {
String directoryPath="dirName";
if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {//判断外部存储是否可用
directoryPath =context.getExternalFilesDir(dir).getAbsolutePath();
}else{//没外部存储就使用内部存储
directoryPath=context.getFilesDir()+File.separator+dir;
}
File file = new File(directoryPath);
if(!file.exists()){//判断文件目录是否存在
file.mkdirs();
}
return directoryPath;
}