Android内部存储和外部存储

前言

在开发任何一款应用,对于存储都是必不可少的。而对于Android来说,Android的存储分为内部存储和外部存储。且android系统对于内外部存储都提供了相应的获取路径API。但是有一点,很多使用者,对于如何使用对于的API,及相关的API获取的路径是对应设备的什么位置并不是很熟悉(对于千万家厂家的现状和及不同版本系统,有的时候甚至有些API是无法使用的)。

Android文件系统目录结构

对于内外存储,我们可以借用Android文件系统目录结构来提高辨识。
Android系统的内核使用的是Linux内核, 所以Android的文件目录结构和Linux系统的文件目录结构类似,Android系统使用虚拟文件系统(VFS), VFS的目录是以/为根节点,根节点下又有不同的节点。而我们的物理存储设备就是挂载都这些节点上,如下图所示:
在这里插入图片描述


备注:借用文件系统目录图,了解一下内外存储区都分别位什么地方:
a、/data/data节点下都是属于内部存储区;
b、/storage/节点下都是属于外部存储区;

1、根节点/data/data:该目录为APK安装目录,如果需要查看路径下的相关文件,需要root才行。
2、根节点/system/:该目录存放系统应用的apk文件,即手机厂商预安装应用的apk文件 (手机厂商只需把需要预安装的apk放在该节点的相应路径下,android系统就会自己解压并安装该apk)。
3、根节点/storage/:该节点是内置存储卡和外置SD卡的挂载点,/storage/emulated/0/是内置存储卡挂载点, /storage/sdcard1是外置SD卡挂载点(不同的设备挂载节点不一样,有些设备可能会挂载到/mnt/节点)。

内部存储,外部存储

内部存储
首先,需要了解一点内部存储不是内存。
其次,内部存储位于系统中很特殊的一个位置,内部存储的文件是应用的私有文件,其他应用(和用户)不能访问这些文件。每个应用访问自己的内部存储是不需要权限的。 当用户卸载应用时,这些文件也会被移除。(理论上来说如果你在创建内部存储文件的时候将文件属性设置成可读,且知道相应的包名,那么其他app也是能够访问自己应用的数据)。
注意:内部存储空间十分有限,另外,它也是系统本身和系统应用程序主要的数据存储所在地,一旦内部存储空间耗尽,手机也就无法使用了。所以对于内部存储空间,我们要尽量避免使用。Shared Preferences和SQLite数据库都是存储在内部存储空间上的。内部存储一般用Context来获取和操作。
外部存储
常规来说,内部存储以外的就是外部存储,可是对于Android的外部存储的理解就相对复杂一些。由于系统版本不同存储的路径不同,大致如下:

一、外部存储的目录
1、2.3之前是/sdcard
2、4.3之前是在/mnt/sdcard
3、4.3之后是在/storage/sdcard

同时内置存储卡有部分可以挂载在/data/data/和/storage/节点下,导致更容易混淆外部存储。且内置存储卡并不等于就是内部存储。因此对于外部的存储就比较难得理解;这只能依据系统版本及厂家对于存储卡挂载的位置进行实际分析。
备注: 1、Android4.4以前读取或写入外部存储(包括公共目录和私有目录)的文件,必须获取 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 系统权限; 2、从Android 4.4 开始,操作私有目录不再需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 权限,但是操作外部存储的公共目录还是需要的申请权限的;

获取路径API


a、系统根目录路径方法
//:/system
String rootDir = Environment.getRootDirectory().toString();
//:/data 用户数据目录(这个方法是获取内部存储的根路径 )
String dataDir = Environment.getDataDirectory().toString();
//:/cache 下载缓存内容目录
String cacheDir = Environment.getDownloadCacheDirectory().toString();


b、内部存储路径方法
//获取当前程序路径 应用在内存上的目录 :/data/data/packname/files
String filesDir = context.getFilesDir().toString();
//应用的在内存上的缓存目录 :/data/data/packname/cache
String cacheDir = context.getCacheDir().toString();
//这个方法是获取某个应用在内部存储中的自定义路径 :/data/data/packname/app_myFile
getDir(“myFile”, MODE_PRIVATE).getAbsolutePath()


c、应用宝下载路径
//获取该程序的安装包路径 :/data/app/packname-3.apk
String packageResourcePath = context.getPackageResourcePath();


d、应用数据库路径
//获取程序默认数据库路径 :/data/data/packname/databases/mufeng
String databasePat = context.getDatabasePath("packname").toString();


e、外部存储路径方法
//主要的外部存储目录:/mnt/sdcard或者/storage/emulated/0或者/storage/sdcard0 
String storageDir = Environment.getExternalStorageDirectory().toString();
//这个方法是获取外部存储的公有根路径:/storage/emulated/0 
String publicDir = Environment.getExternalStoragePublicDirectory(“”).getAbsolutePath()
//这个方法是获取外部存储的私有根路径 /storage/emulated/0/Android/data/packname/files 
String externalFilesDir = Environment.getExternalFilesDir(“”).getAbsolutePath()
//:/mnt/sdcard/Pictures或者/storage/emulated/0/Pictures或者/storage/sdcard0/Pictures
String publicPCDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
//应用在外部存储上(私有)的目录 :/storage/emulated/0/Android/data/packname/files/Movies
String externalMVFilesDir = context.getExternalFilesDir(Environment.DIRECTORY_MOVIES).toString();
//应用的在外部存储上的缓存目录 :/storage/emulated/0/Android/data/packname/cache
String externalCacheDir = context.getExternalCacheDir().toString();


//获取SD卡是否存在:mounted
String storageState = Environment.getExternalStorageState().toLowerCase();
//设备的外存是否是用内存模拟的,是则返回true。(API Level 11)
boolean isEmulated = Environment.isExternalStorageEmulated();
//设备的外存是否是可以拆卸的,比如SD卡,是则返回true。(API Level 9)
boolean isRemovable = Environment.isExternalStorageRemovable();


//查询所有外部存储路径
File[] files = context.getExternalFilesDirs();


备注
1、由于Android系统特殊情况 ,同一个存储设备经过分区后,不同的分区可以挂载到不同的节点上。
2、内部存储的使用是不需要权限的,由于内部存储属于应用的私有存储区域,其它应用不可访问,且当应用被卸载时,内部存储中的文件将会被删除。
3、外部存储分为公共目录和私有目录,外部存储是可以全局访问的,但需要申请权限:

	Android4.4前访问私有目录和公共目录都需要申请 WRITE_EXTERNAL_STORAGE 权限
	Android4.4后访问私有目录不需要申请权限,但公共目录是需要申请 WRITE_EXTERNAL_STORAGE 权限

4、版本大于17的讲舍弃常量 MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE ,且 Android N 开始,使用这些常量将会引发 SecurityException异常。
5、有内存存储的空间有限,如果缓存的数据量比较大,需要慎用内存储中。
6、如果保存的数据需与其他进程共享,需讲数据保存到外部存储的公共目录中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值