内部存储
概念
注意内部存储不是内存。内部存储位于系统中很特殊的一个位置,如果你想将文件存储于内部存储中,那么文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。
访问内部存储的API方法
1、Environment.getDataDirectory()
2、getFilesDir().getAbsolutePath()
3、getCacheDir().getAbsolutePath()
4、getDir(“myFile”, MODE_PRIVATE).getAbsolutePath()
外部存储
概念
最容易混淆的是外部存储。外部存储在4.4系统以前:手机自身带的存储卡就是内部存储,而扩展的SD卡就是外部存储;4.4系统开始:手机将机身存储存储(手机自身带的存储叫做机身存储)在概念上分成了”内部存储internal” 和”外部存储external” 两部分,而SD卡也是外部存储的话,如何区分。
- 其中/storage/emulated/0目录就是机身存储的外部存储路径
- 而/storage/B3E4-1711/就是SD卡的路径
访问外部存储的API方法
1、Environment.getExternalStorageDirectory().getAbsolutePath()
2、Environment.getExternalStoragePublicDirectory(“”).getAbsolutePath()
3、getExternalFilesDir(“”).getAbsolutePath()
4、getExternalCacheDir().getAbsolutePath()
不同Android版本
getDataDirectory,getFilesDir,getCacheDir,getDir,getExternalStorageDirectory,getExternalStoragePublicDirectory,getExternalFilesDir,getExternalCacheDir,getExternalCacheDir,getRootDirectory的区别和联系
上面这些方法,我们可能似曾相识,但是对于有些同学来说却又很难分清出,主要还是不同的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及以上的系统才会返回上面的结果,也即4.4以前的系统没插SD卡的话,就没有外部存储,它的SD卡就等于外部存储;
- getExternalFilesDir(“”)和getExternalCacheDir()获取的是机身存储的外部存储部分
- getExternalFilesDirs(Environment.MEDIA_MOUNTED)获取SD卡的存储路径
…………………………………………………………………………………………
Environment.getDownloadCacheDirectory() = /cache
Environment.getRootDirectory() = /system
这两个方法没什么说的了,每个版本的android系统都一样
…………………………………………………………………………………………
上面的方法可以分为三类,用横线隔开了。
- /data目录下的文件物理上存放在我们通常所说的内部存储里面
- /storage目录下的文件物理上存放在我们通常所说的外部存储里面,API方法都带了一个External
- /system用于存放系统文件,/cache用于存放一些缓存文件,物理上它们也是存放在内部存储里面的
getFilesDir().getAbsolutePath()和getCacheDir().getAbsolutePath()区别
getFilesDir获取的是files目录,getCacheDir获取的是cache目录,它们位于同一级目录,只是为了用来存放不同类型的数据的
cache下存放缓存数据,databases下存放使用SQLite存储的数据,files下存放普通数据(log数据,json型数据等),shared_prefs下存放使用SharedPreference存放的数据。
getFilesDir().getAbsolutePath()和getExternalFilesDir(“”).getAbsolutePath()的区别
- /data/user/0/packname/files:是内部存储
- /storage/emulated/0/Android/data/packname/files:是外部存储
- 它们的路径都带有包名,表明是这个APP的专属文件,这类文件应该是随着app卸载而一起被删除的,并且我们在设置里面清除该应用的数据时,这两个文件夹下的数据都会被清除。
内部存储与外部存储都有APP专属文件,我们该使用哪个
应用外部存储的,因为内部存储本身就比较小,而且已经存储了一些系统的文件,因此内部存储我们尽量不要去使用。但是当手机没有外部存储时,我们还是得使用内部存储,一般程序员会做判断是否有外部存储,没有再使用内部存储,代码如下:
public static String getFilePath(Context context,String dir) {
String directoryPath="";
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;
}
清除数据和清除缓存到底清除了什么数据
- /data/user/0/packname/files它是用来存储普通数据的
- /data/user/0/packname/cache它是用来存储缓存数据的
很多人就以为我清除数据时清除的肯定就是files下的数据,而我清除缓存数据时清除的肯定就是cache下的数据,但是事实却不是这样的。
清除缓存
我们知道应用程序在运行过程中需要经过很多过程,比如读入程序,计算,输入输出等等,这些过程中肯定会产生很多的数据,它们在内存中,以供程序运行时调用。所以清除缓存清除的是APP运行过程中所产生的临时数据。
清除数据
清除数据才是真正的删除了我们保存在文件中的数据(永久性数据,如果不人为删除的话会一直保存在文件中)例如当我们在设置里面清除了某个应用的数据,那么/data/user/0/packname/和/storage/emulated/0/Android/data/packname/下的文件里面的数据会全部删除,包括cache,files,lib,shared_prefs等等。
/storage/sdcard,/sdcard,/mnt/sdcard,/storage/emulated/0之间的关系
- 在4.1系统中,getExternalStorageDirectory方法获取到的路径为/storage/sdcard0;
- 4.2系统中getExternalStorageDirectory方法获取到的路径为/mnt/sdcard,因为4.2是模拟器打印的结果,如果是真机的话也是/storage/sdcard0;
- 4.4的getExternalStorageDirectory方法获取到的路径为/storage/emulated/0,它的SD卡存储路径为/storage/sdcard1;
- 6.0的getExternalStorageDirectory方法获取到的路径为/storage/emulated/0,它的SD卡存储路径为/storage/B3E4-1711;
- 另外根据测试在4.0上getExternalStorageDirectory方法获取到的路径为/mnt/sdcard。
内存,内部存储,外部存储,机身存储
内存
我们在英文中称作memory,内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,所以说它是用于计算机运行时的,它不是用来存储数据的。
内部存储,外部存储
内部存储我们称为InternalStorage,外部我们称为ExternalStorage,这两个概念来自于早期的Android智能机。
- 4.4以前,内置存储就是内部存储,外置SD卡就是外置存储。我们通过getDataDirectory就可以获取内置存储根路径,通过getExternalStorageDirectory就可以获取外置SD卡根路径。
- 4.4以后,外部存储就包含两部分了,其中通过getExternalStorageDirectory获取的是机身存储的外部存储,而外置SD卡我们则需要通过getExternalDirs遍历来获取了。
机身存储
机身存储是指手机自身携带的存储空间,出厂时就已经有了,4.4以前机身存储就是内部存储,4.4及以后机身存储包含了内部存储和外部存储