白日放歌须纵酒,青春作伴好还乡。这篇文章主要讲述Android中的File存储相关的知识,希望能为你提供帮助。
关于android的File存储,这里先说下java中的File类,根据面向对象的思想,Java中对文件的操作也进行了对象的封装,这个操作文件的类就是File类,File提供了丰富的api来进行文件的操作,比如常见的createNewFile(),mkdir(),mkdirs(),exists(),isFile(),isDictory(),renameto(),delete(),getName(),getPath()....方法比较多,读者可以自行通过api文档查看,同样这一套的文件操作在Android中也适用。
下面对几个常用的api进行说明举例。
File构造函数
/** *这里通过将给定路径名字符串转换为抽象路径名来创建一个新File实例。 *然后执行file.createNewFile(); 如果该文件存在,则创建失败,不存在则创建,返回一个boolean值 */ File file=new File(String pathname);
/** *这里根据parent抽象路径名和child路径名字符串创建一个新File实例。 *执行file.createNewFile(); 如果parent抽象路径名不存在,或者文件已经创建过,依然不能创建成功。 */ File file=new File(File parent,String child);
/** *根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 *执行file.createNewFile(); 如果parent抽象路径名不存在,或者文件已经创建过,依然不能创建成功。 */ File file=new File(String parentpath,String child);
File常用方法
- createNewFile(); 如果文件已经存在,则创建失败,否则成功创建,还有其他可能
- mkdir(); 创建文件夹,注意:如果创建目标文件夹的父级目录不存在,就会创建失败
- mkdirs(); 创建多级目录,父级文件目录不存在的话,会自动创建父级目录。
- isFile(); 判断是否是一个文件
- isDictory(); 判断是否是一个文件夹
- delete(); 删除文件或者文件夹,注意要是删除文件夹的时候,文件夹里还有文件或者文件夹,则不能删除,意思是只能删除一个空文件夹。
- exists(); 判断文件或者文件夹是否存在
- getName(); 获取文件或者文件夹的名称
- getPath(); 获取相对路径
- getAbsolutePath(); 获取绝对路径
- length(); 获取文件或者文件夹的长度
- 在介绍如何在Android平台下进行文件的读取之前,有必要了解Android平台下的数据存储规则。在其他的操作系统如Windows 平台下,应用程序可以自由地或者在特定的访问权限基础上访问或修改其他应用程序名下的文件等资源,而在Android平台下,一个应用程序中所有的数据都是私有的。
- 当应用程序被安装到系统中后,其所在的包会有一个文件夹用于存放自己的数据,只有这个应用程序才有对这个文件夹的写入权限,这个私有的文件夹位于Android系统的/data/data/< 应用程序包名> 目录下,其他的应用程序都无法再这个文件夹中写入数据。除了存放私有的数据文件夹外,应用程序也具有SD卡的写入权限。
- 使用文件I/O 方法可以直接往手机中存储数据,默认情况下这些文件不可以被其他的应用程序访问。Android平台支持 java平台下的 文件I/O操作, 主要使用FileInputStream 和 FileOutputStream 这两个类来实现文件的存储与读取。获取这两个类对象的方式有两种。
- 第一种方式就是像Java平台下的实现方式一样通过构造器直接创建,如果需要向打开的文件末尾写入数据,可以通过使用构造器FileOutputStream(File file, boolean append)将 append设置为true来实现。不过需要注意的是采用这种方式获得FileOutputStream 对象时如果文件不存在或不可写入时,会抛出 FileNotFoundException 异常。
- 第二种获取 FileInputStream 和 FileOutputStream 对象的方式是调用 Context.openFileInput 和 Context.openFileOutput两个方法来创建。
- openFileInput(String filename) 打开应用程序私有目录下的的指定私有文件以读入数据,返回一个FileInputStream 对象,如果该文件不存在,依然会发生异常,FileNotFoundException
- openFileOutput(String fileName,int mode) 打开应用程序私有目录下的的指定私有文件以写入数据,返回一个FileOutputStream 对象,如果文件不存在就创建这个文件。
- fileList() 搜索应用程序私有文件夹下的私有文件,返回所有文件名的String数组
- deleteFile(String fileName) 删除指定文件名的文件,成功返回true,失败返回false
常量 含义
MODE_PRIVATE
默认模式,文件只可以被调用该方法的应用程序访问
MODE_APPEND
如果文件已存在就向该文件的末尾继续写入数据,而不是覆盖原来的数据。
MODE_WORLD_READABLE
赋予所有的应用程序对该文件读的权限。
MODE_WORLD_WRITEABLE
赋予所有的应用程序对该文件写的权限。
但是Android 4.2开始,Android不推荐使用,MODE_WORLD_READABLE ,MODE_WORLD_WRITEABLE这两种模式。
App在手机上保存文件或者缓存数据时,应该遵守以下几点:
- 不要随意占用用户的内置存储。
- 不要随意在SD卡上新建目录,应该放置自己应用包名对应的扩展存储目录下,卸载App时可以被自动清除。
- 对占用的磁盘空间有上限,并按照一定的策略进行清除。
应用私有存储(内置存储) 获取方式:
Context.getFileDir():获取内置存储下的文件目录,可以用来保存不能公开给其他应用的一些敏感数据如用户个人信息
Context.getCacheDir():获取内置存储下的缓存目录,可以用来保存一些缓存文件如图片,当内置存储的空间不足时将系统自动被清除
绝对路径:
Context.getFileDir():/data/data/应用包名/files/
Context.getCacheDir():/data/data/应用包名/cache/
写权限:不需要申请
这是手机的内置存储,没有root的过的手机是无法用文件管理器之类的工具查看的。而且这些数据也会随着用户卸载App而被一起删除。这两个目录其实就对应着设置-> 应用-> 你的App-> 存储空间下面的清除数据和清楚如下图所示
文章图片
应用扩展存储(SD卡) 获取方式:
Context.getExternalFilesDir():获取SD卡上的文件目录
Context.getExternalCacheDir():获取SD卡上的缓存目录
绝对路径:
Context.getExternalFilesDir():SDCard/Android/data/应用包名/files/
Context.getExternalCacheDir():SDCard/Android/data/应用包名/cache/
写权限:
API < 19:需要申请
API > = 19:不需要申请
既然是SD卡上的目录,那么是可以被其他的应用读取到的,所以这个目录下,不应该存放用户的敏感信息。同上面一样的,这里的文件会随着App卸载而被删除,也可以由用户手动在设置界面里面清除。
公共存储(SD卡) 获取方式:Environment.getExternalStorageDirectory()
绝对路径:SDCard/你设置的文件夹名字/
写权限:需要申请
如果我们的App需要存储一些公共的文件,甚至希望下载下来的文件即使在我们的App被删除之后,还可以被其他App使用,那么就可以使用这个目录。这个目录是始终需要申请SD写入权限的。
Android6.0下应该把文件放到哪里?
根据最开始提到的规则,其实如果仅仅是做了简单的图片缓存工作,那么我们应该把图片缓存放到/data/data/应用包名/cache/或者SDCard/Android/data/应用包名/cache/,因为在6.0系统(API23)时,不需要申请权限就可以向这两个目录写入文件。而且/data/data/应用包名/cache/目录,是内置存储的应用私有缓存目录,在系统空间不够时还会被自动清除,对于图片缓存来讲也是一个不错的管理策略,不过谷歌建议我们最好还是自己实现缓存清除管理,例如用DiskLruCache。
【Android中的File存储】参考文章:http://unclechen.github.io/2016/03/06/Android6.0%E6%9D%83%E9%99%90%E9%80%82%E9%85%8D%E4%B9%8BSD%E5%8D%A1%E5%86%99%E5%85%A5/
推荐阅读
- Android开发中遇到的问题——Android中WARNING: Application does not specify an API level requirement!的解决方法
- H5跨平台开发app之横竖屏导致的图表混乱问题
- android studio 中jni底层日志的打印
- Firebase(实时数据库更新和删除)
- Firebase实时数据库中的数据组织
- Firebase SDK(使用电子邮件链接进行身份验证)
- 一个关于混淆的 Native 崩溃分析
- 购买游戏笔记本电脑前需要注意的8件事
- DTX-XFM光缆测试模块