在Android开发中,我们很多时候会涉及到Android手机文件的存取,包括SQLite数据库、sharePreference以及其他文件的存取,由于手机外部扩展存储的存在,很多时候我们会对Android的文件目录很模糊,今天通过看了网上了几篇文章,对重要的Android目录的解析以及操作的方法做了理解和记录,在这里做出分享,方便共同学习。
Android系统中很重要的几个目录结构就是/system,/data,/mnt,开发中较多的是/data,/mnt,/sdcard,/storage。下面对这五个文件目录一一介绍,以Android4.2.2的目录结构为例。
一、/system
system //系统相关的绝大部分东西都在该目录下
|-- lost+found//存放系统检查结果,yaffs文件系统都会有这个类似回收站的文件夹
|-- app//主要存放的是系统应用程序,区别于存放自己安装应用程序的目录/data。
|-- bin//从bin文件夹名称可以看出是binary二进制的程序,里面主要是Linux系统自带的组件
|-- build.prop//Android系统重要的属性文件,记录了系统的设置和改变,类似於/etc中的文件。
|-- etc//系统配置文件,保存的都是系统的配置文件,比如APN接入点设置等核心配置。
|-- fonts//字体文件夹,除了标准字体和粗体、斜体外可以看到文件体积最大的可能是中文字库,或一些unicode字库
|-- framework//主要是一些核心的文件,从后缀名为jar可以看出是是系统平台框架.是JAVA平台的一些核心文件,属於JAVA平台系统框架文件。里面的文件都是.jar和.odex文件。
|-- lib//存放的主要是系统底层库,如平台运行时库
|-- media//铃声音乐文件夹,除了常规的铃声外还有一些系统提示事件音
|-- sounds//默认的音乐测试文件,仅有一个test.mid文件,用于播放测试的文件。
|-- usr//用户文件夹,包含共享、键盘布局、时间区域文件
|-- vendor
|-- xbin//存放了很多系统管理工具,这些工具不是到toolbox的链接,每个都是可执行程序。
正常情况下,/system是不允许写操作的,但可以root后使用root用户进行写操作
Environment.getRootDirectory() = /system
##二、/data
data //存放用户安装的软件以及各种数据
|-- app//system/app 放的是系统预载的应用程式执行档。而这里放的是使用者自己安装的应用程式执行档(.apk)
|-- dontpanic
|-- misc
|-- local
|-- data //当用Context.openFileOutput()所建立的档案,都放在该目录下的files内。Context.getSharedPreferences()所建立的preferences 档(.xml),放在shared_pref目录中,而且只能被app以自己的默认的方式访问,存在此文件夹中各自包下的文件不能被用户和其他app访问
|-- app-private
|-- app-asec
|-- app-lib
|-- property
|-- ssh
|-- dalvik-cache//
|-- resource-cache
|-- drm
|-- media
|-- lost+found
|-- smc
|-- radio
|-- user
|-- system
|-- backup
|-- NVM0
|-- NVM1
|-- NVM2
|-- NVM13
|-- NVM3
|-- NVM6
|-- anr // 当你的应用程式发生ANR (Application is Not Responding) 错误时,Android 会自动将问题点的code stack list 写在anr/traces.txt内,你直接用cat 命令就可以看他的内容
|-- NVM5
|-- cal.bin
|-- tombstones
首先内部存储路径为/data/data/youPackageName/,下面讲解的各路径都是基于你自己的应用的内部存储路径下,所有内部存储中保存的文件在用户卸载应用的时候会被删除。
① files
Context.getFilesDir(),该方法返回/data/data/youPackageName/files的File对象。
Context.openFileInput()与Context.openFileOutput(),只能读取和写入files下的文件,返回的是FileInputStream和FileOutputStream对象
Context.fileList(),返回files下所有的文件名,返回的是String[]对象。
Context.deleteFile(String),删除files下指定名称的文件。
②cache
Context.getCacheDir(),该方法返回/data/data/youPackageName/cache的File对象。
③custom dir
getDir(String name, int mode),返回/data/data/youPackageName/下的指定名称的文件夹File对象,如果该文件夹不存在则用指定名称创建一个新的文件夹。
Environment.getDataDirectory() = /data
Environment.getDownloadCacheDirectory() = /cache
context.getCacheDir() = /data/data/com.mt.mtpp/cache
##三、/mnt
mnt// 挂载点目录
|-- sdcard//指向/sdcard目录 ,SD卡中的EXT2分区的挂载目录
|-- obb//
|-- asec//
|-- secure//
|-- |–asec//
|-- |–staging//
|-- shell//
|-- |–emulated//
|-- |–legacy//
Environment.getExternalStorageDirectory() = /mnt/sdcard
context.getExternalCacheDir() = /mnt/sdcard/Android/data/com.mt.mtpp/cache
##四、/sdcard
sdcard// 是SD卡中的FAT32文件系统挂载的目录.SD卡中的EXT2分区的挂载目录
|-- Music
|-- Podcasts
|-- Ringtones
|-- Alarms
|-- Notifications
|-- Pictures
|-- pris
|-- Download
|-- DCIM//图库,相机随机缓存文件夹,记录功能设置的参数,需要及时清理。一些第三方相机软件拍出的相片也会保存在这里,比如360或晕影相机等。
|-- |–Camera//
|-- |–100ANDRO//
|-- android_secure//官方app2sd的产物,存储了相关的软件使用认证验证,删除之后SD卡中的软件将无法使用。
|-- Android//存放重要的程序数据,比如google:map的地图缓存,误删掉后地图还需重新下载。
|-- backups//包含重要的备份文件,比如联系人导出到SD卡会导入到此文件夹。
|-- bugtogo//系统出现问题的时候会形成一些报告文件,存放在此文件夹。
|-- data//缓存数据文件夹,与Android类似。例如,“截图助手”截图保存在
|-- LOST.DIR//卡上丢失或出错的文件会移动到这里,此目录删了会自动生成。
|-- SystemAppBackup//SystemApp remove(深度卸载)备份系统文件后,备份文件保存的目录。
|-- bugreports//升级系统或刷机,系统和程序发生兼容错误报告列表(包括内存使用全部内容)将保存在这个文件,重起机器可以删除。
|-- .keepsafe//隐藏类的软件、加密保存文件地址存放于此。
|-- .thumbs//浏览或使用某一软件,以及使用某一文件夹后用于记录次数和内容的文件,随机产生,需要定期不断清除,长时间不清理会大量占用储存卡的有效空间。
|-- openfeint//打开联接网络后的一个启动程序,它广泛植入移动类平台发布的软件或游戏,是更新下载或评论反馈信息的记录地址,可删除。
|-- com//播放类软件在收看播放影视节目生成的文件将存放于此,可以对制作方反映回馈信息,可以删除。
|-- Download(download)//大写字母的是网络联接下载文件目录,小写字母的是手机自身(蓝牙,近场等)存放下载传输文件,不要误删。
|-- albumart//音乐专辑封面的缓存文件夹。
|-- albums//相册缩略图的缓存文件夹。
|-- cmp//音乐的缓存文件夹。
|-- Playlists//播放列表的缓存文件夹。
|-- VPN//VPN数据的缓存目录。
|-- My documents//手机启用各种程序任务记录的文档,需要定期清除,长时间不清理会占用SD卡较大内存。
|-- .nomedia//手机中隐藏的音频、图片文件夹都会在这里显示,可以自设在相关文件夹中。
|-- media//使用电话通话录音软件或在线浏览视频等媒体产生的音频文件记录存档将保存在此。
|-- .medieval_software//启用蓝牙传输软件时,记录任务保存文件的目录。
|-- extracted//解压缩软件默认的解压目录。
|-- .xxx//XXX的缓存文件。
|-- libs
|-- Vlog.xml
|-- bugreports
|-- burstlyImageCache
|-- com.sinyee.babybus
|-- msf
|-- Amap
|-- data
|-- tmp
|-- detect
|-- lehe_yy_s
|-- aquery
|-- movie
|-- extensions
|-- zh-CN
|-- classic
public String getSDPath(){
File sdDir = null;
boolean sdCardExist = Environment.getExternalStorageState()
.equals(Android.os.Environment.MEDIA_MOUNTED); //判断sdcard是否存在
if (sdCardExist)
{
sdDir = Environment.getExternalStorageDirectory();//获取根目录
}
return sdDir.toString();
}
##五、/storage
storage //
|-- sdcard0//指向/sdcard目录 ,SD卡中的EXT2分区的挂载目录
|-- emulated//
|-- |–legacy//指向/sdcard目录,SD卡中的EXT2分区的挂载目录
/sdcard是/mnt/sdcard的符号链,指向/mnt/sdcard,/storage/sdcard0 是sdcard的分区
最后,讲一下Android的内部存储与外部存储:
大多数Android设备提供两种存储方式:内置的非易失的内存(内部存储)和可移动的存储例如micro SD卡(外部存储)。一些设备将永久内存分为内部和外部两部分,因此即使没有外部存储,依旧有两种存储空间。不管有没有外部存储,API的方法都是一样的。
内部存储:
始终都是可用的
保存的文件只能被你的app以默认的方式访问
卸载app,系统从内部存储中删除你app的所有文件
内部存储适用于你不想用户或其他app访问你的文件
外部存储:
不总是可用的(用户可能将外部存储以USB方式连接, 一些情况下会从设备中移除)
是全局可读的(world-readable),因此一些文件可能不受控制地被读取
卸载app,只删除你存储在getExternalFilesDir()目录下的文件
外部存储适用于不需要存储限制的文件以及你想要与其他app共享的文件或者是允许用户用电脑访问的文件
app默认安装在内部存储中,通过指定android:installLocation 属性值可以让app安装在外部存储中。
获取外部存储权限:
读与写:
复制代码代码如下:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
读:
复制代码代码如下:
<manifest ...>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
在内部存储保存文件不需要任何权限,你的app在内部存储中总是有读写权限。
在内部存储中保存文件:
获取适当的目录:
getFilesDir() app文件在内部存储中的目录
getCacheDir() app临时缓存文件在内部存储中的目录
调用openFileOutput()获取FileOutputStream写入文件到内部目录
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
调用 createTempFile()缓存一些文件:
public File getTempFile(Context context, String url) {
File file;
try {
String fileName = Uri.parse(url).getLastPathSegment();
file = File.createTempFile(fileName, null, context.getCacheDir());
catch (IOException e) {
}
return file;
}
在外部存储中保存文件:
由于外部存储不总是可用的,正如上面所提到的,用户可能移除了SD卡或USB模式连接了电脑。所有在访问之前需要确认外部存储是可用的。
可以调用 getExternalStorageState() 返回外部存储的状态,如果返回的是MEDIA_MOUNTED,则可以读写在外部存储的文件。
//判断外部存储是否可以读写
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
//判断外部存储是否至少可以读
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
外部存储可以被用户或其他app访问,我们可以保存两种文件到外部存储:
1.公共文件(public files)
可以自由地被用户或其他app访问的文件,当用户卸载app时,这些文件依然存在。
调用 getExternalStoragePublicDirectory()获得目录,保存公共文件到外部存储:
public File getAlbumStorageDir(String albumName) {
// 获得用户公共的图片目录
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
2.私有文件(private files)
属于你app的文件,当用户卸载时,这些文件将被删除。
调用getExternalFilesDir() 获得适当的目录,保存私有文件到外部存储:
public File getAlbumStorageDir(Context context, String albumName) {
// 获得应用私有的图片目录
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
删除文件:myFile.delete();
删除保存在内部存储中的文件:myContext.deleteFile(fileName);
我们应该删除所有用getCacheDir() 生成的文件以及不再需要的文件
文章引用自:https://my.oschina.net/limiaoneu/blog/543169