当应用程序被安装到系统中后,其所在的包会有一个文件夹用于存放自己的数据,只有这个应用程序才有对这个文件夹的写入权限,这个私有的文件夹位于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两个方法来创建。除了这两个方法外,Context对象还提供了其他几个用于对文件操作的方法,如下所示
Context对象中文操作的API及说明
方法名 说明
打开应用程序私有目录下的的指定私有文件以读入数据,返回一个FileInputStream 对象
打开应用程序私有目录下的的指定私有文件以写入数据,返回一个FileOutputStream 对象,如果文件不存在就创建这个文件。
搜索应用程序私有文件夹下的私有文件,返回所有文件名的String数组
删除指定文件名的文件,成功返回true,失败返回false
在使用openFileOutput方法打开文件以写入数据时,需要指定打开模式。默认为零,即MODE_PRIVATE。不同的模式对应的的含义如下:
openFileOutput方法打开文件时的模式
常量 含义
默认模式,文件只可以被调用该方法的应用程序访问
如果文件已存在就向该文件的末尾继续写入数据,而不是覆盖原来的数据。
赋予所有的应用程序对该文件读的权限。
赋予所有的应用程序对该文件写的权限。
本人刚开始把文件写入程序私有目录的时候用的是OpenFileOutput也就是上面介绍的第一种方法,但是很是费劲,因为返回的是fileoutputstream很多方法都没有(例如你写一个断点续传的功能就很麻烦)但是看到这篇文章后感觉既然可以用第一种方法来做那么我们可不可以直接用File file = new File();的方法来做呢,试了一下果然可以。然后回头想一想也很合理。你想啊私有目录是这个程序自己的目录我在自己的程序里访问自己的目录结果还不能访问需要这个那个的限制这也将不通啊,是吧,我访问公共的SD卡都没问题,访问自己的目录倒是有问题了,合理吗?呵呵,之前就是没试试啊。看来还是不能迷信常理,还是要多动手试试。
最近在研究Android断点续传的相关的技术. 这类文章在网上到处都是,基本原理都是在写入文件的时候在数据库中记录已经下载的文件大小. 当暂停后再次向服务器请求数据时传入这个数值,即可得到后续的数据. 然后调用RandomAccessFile这个对象的seek方法,在已经写入的文件中继续追加数据.
那么现在面临一个问题,那就是如果没有sdcard的时候,这个怎么处理?
熟悉Android的开发者都知道,如果想在应用中保存文件数据,除了可以在sdcard中写入,也可以在/data/data/packegename/file中保存。通常方法如下:
这样便会打开一个文件输出流进行文件的流写入操作. 但是这并不满足断电续传的要求,那就是FileOutputStream类并没有提供seek方法,所以不能在任意文件位置进行数据写入. 这对于断点续传技术来说是致命的.
如果直接使用如下代码进行强行文件写入是会报错的:
这会提示创建文件失败!
这是因为默认情况下,应用的数据目录是没有w权限的,只有读和修改的权限,所以无法创建新的文件.
重点来了,我们用下面的方法来曲线救国,请看代码:
第一步:在应用数据根目录下创建一个自定义的目录.
第二步:给此目录赋予可读写权限.
第三步:在此目录下创建任意文件.
以下是运行结果:
这样创建的文件就可以生成RandomAccessFile文件进行任意位置的读写操作了. 另外强调一下,这个方法无论手机是否拥有Root权限都是可行的. 希望对有需要的开发者们有帮助.