Android文件存储:内部存储,外部存储及其路径
Android系统数据存储分为内部存储和外部存储,内部存储是手机系统自带的存储,一般空间都不大,外部存储一般是SD卡的存储,空间一般都比较大。一般我们会把存储内容放在外部存储空间里。在使用过程需要注意事项:
先判断SD卡是否可用,可用时优先使用SD卡的存储,不可用时用内部存储
存储在SD卡上时,可以在SD卡上新建任意一个目录存放,也可以存放在应用程序内部文件夹(APP专属文件),区别是在SD卡的任意目录存放时内容不会随应用程序的卸载而消失,而在应用程序内部的内容会随应用程序卸载消失。
一般缓存文件放在应用程序内部,用户主动保存的文件放在SD卡上的文件夹里。
1.内部存储,外部存储的概念
内部存储
概念:内部存储位于系统中很特殊的一个位置,如果你想将文件存储于内部存储中,那么文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。从技术上来讲如果你在创建内部存储文件的时候将文件属性设置成可读,其他app能够访问自己应用的数据,前提是他知道你这个应用的包名,如果一个文件的属性是私有(private),那么即使知道包名其他应用也无法访问。 内部存储空间十分有限,因而显得可贵,另外,它也是系统本身和系统应用程序主要的数据存储所在地,一旦内部存储空间耗尽,手机也就无法使用了。所以对于内部存储空间,我们要尽量避免使用。Shared Preferences和SQLite数据库都是存储在内部存储空间上的。
注意内部存储不是内存。内部存储一般用Context来获取和操作。
根目录($rootDir):/data,通过 Environment.getDataDirectory() 获取。
应用程序目录($packageName):$rootDir/data/packageName(不一定,不同设备可能不同)
应用缓存目录:$packageName/cache,通过Context.getCacheDir()获取。
应用文件目录:$packageName/files,通过Context.getFilesDir()获取。Context.getFileStreamPath(String filePath)返回以name为文件名的子文件目录,若filePath为空,则返回文件根目录/data/user/0/packageName/files。
Environment.getDataDirectory().getAbsolutePath() /data
getCacheDir().getAbsolutePath() /data/user/0/packageName/cache
getFilesDir().getAbsolutePath() /data/user/0/packageName/files
getFileStreamPath("filePath").getAbsolutePath() /data/user/0/packageName/files/filePath
外部存储
概念:对于早期Android 的系统手机自身带的存储卡就是内部存储,而扩展的SD卡就是外部存储。但是随着Android系统的不断升级,从4.4的系统开始,大部分都将机身存储扩展到了8G以上,那么这个是内部存储吗,不是的!!!,它们依然是外部存储,也就是说4.4系统及以上的手机将机身存储存储(手机自身带的存储叫做机身存储)在概念上分成了”内部存储internal” 和”外部存储external” 两部分。既然是外部存储,那有人又有疑惑了,那4.4系统及以上的手机要是插了SD卡呢,SD卡又是什么呢,如果SD卡也是外部存储的话,那怎么区分机身存储的外部存储跟SD卡的外部存储呢?对,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(TAG,file);
}
}
如果你的手机插了SD卡的话,那么它打印的路径就有两条了,例如我的华为荣耀7插了SD卡,它的结果如下:
/storage/emulated/0/Android/data/packname/files/mounted
/storage/B3E4-1711/Android/data/packname/files/mounted
其中/storage/emulated/0目录就是机身存储的外部存储路径
而/storage/B3E4-1711/就是SD卡的路径
他们统称为外部存储。
根目录($rootDir):/storage/emulated/0(不一定,不同设备可能不同),通过 Environment.getExternalStorageDirectory() 获取。
应用程序目录($packageName):$rootDir/Andorid/data/包名
应用缓存目录:$packageName/cache,通过Context.getExternalCacheDir()获取。
应用文件目录:$packageName/files,通过Context.getExternalFilesDir(String type)。type系统给我们提供了很多常用的类型,比如图片和下载等等:
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
路径如下:
Environment.getExternalStorageDirectory() /storage/emulated/0
getExternalCacheDir() /storage/emulated/0/Android/data/packageName/cache
getExternalFilesDir("") /storage/emulated/0/Android/data/packageName/files
getExternalFilesDir("filePath") /storage/emulated/0/Android/data/packageName/files/filePath
getExternalFilesDir(Environment.DIRECTORY_DCIM) /storage/emulated/0/Android/data/packageName/files/DCIM
观察上述文件路径,我们发现除了Environment.getDataDirectory().getAbsolutePath() 和Environment.getExternalStorageDirectory()之外,内部存储和外部存储所有的路径都会在packageName之下,即APP专属文件。
2.什么是APP专属文件?
所谓专属文件就是它是属于某个具体的应用的,他的文件路径都带有相应的包名,当APP卸载时,它们会随应用一起删除,当我们在设置里面手动清除某个应用数据时(不是清除缓存),它们也会一起被清掉。Android使用这种专属文件的目的就是为了方便文件管理,避免文件随意存储,显得很乱,另一个目的就是为了当应用被卸载时不会留下很多垃圾文件。
3.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;
}
4.公共存储目录
该目录下文件不会随APP卸载而消失。
Environment.getExternalStorageDirectory() /storage/emulated/0
Environment.getExternalStoragePublicDirectory("") /storage/emulated/0
Environment.getExternalStoragePublicDirectory("filePath") /storage/emulated/0/filePath
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) /storage/emulated/0/Pictures
参考:https://blog.csdn.net/u010937230/article/details/73303034
长安三日 原创文章 33获赞 14访问量 12万+ 关注 私信 展开阅读全文作者:长安三日
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341