Android中文件读写操作

        Android开发中,离不开对文件的操作。本文首先介绍了使用java对文件进行基本的读写操作,而后介绍了Android中读取Assets与raw文件夹中的数据,最后介绍了Android中读写内部存储与外部存储。

详细代码:读取Assets与raw文件夹中的数据    读写内部存储与外部存储

一、文件的基本操作

java中file类的定义:An abstract representation of file and directory pathnames.

创建文件时,先实例化file类,再调用createNewFile方法

传入文件路径可以实例化file对象

Filefile=newFile(FileUtil.FILE_NAME);

通过file.exists()可以判断文件是否存在,存在返回true

//创建文件

file.createNewFile();

可以获取文件的各种属性

"文件名为:"+file.getName()"文件的绝对路径为"+file.getAbsolutePath()

//文件存放在工程根目录下,相对路径只有文件名

"文件的相对路径为"+file.getPath();

//文件大小,单位bytes,"文件大小为:"+file.length()+”字节"

"文件是否可读"+file.canRead()"文件是否可写"+file.canWrite()"文件是否隐藏"+file.isHidden()

文件重命名,调用renameTo()方法,需要传入File类作为参数

Filefile=newFile(FileUtil.FILE_NAME);

FilenewFile=newFile("AnotherFile.txt");

file.renameTo(newFile);

文件重命名只针对文件本身,重命名后File对象不变,调用getName()会获得原值

删除文件,当文件存在时,调用delete()方法删除文件

Filefile=newFile(FileUtil.FILE_NAME);

if(file.exists()){file.delete();}

创建文件夹,同样先实例化file类,然后调用mkDir或mkDirs方法进行文件夹的创建

//文件夹,创建多级目录时,不能使用"/"作为分隔符,会因为操作系统的不同而出现异常

//需要使用File.separator(File类中默认的分隔符)

publicstaticfinalStringFOLDER_NAME="NewFolder2"+File.separator+"SubFolder2”;

//当使用file.mkdir时,如果有任意一级的文件夹不存在时都不会完成创建,file.mkdir();

//使用mkdirs创建文件夹时,有文件夹时,创建下一级文件,否则先创建它本身,再创建下一级文件夹

file.mkdirs();创建时尽量使用mkDirs

删除文件夹,调用file.delete()方法

二、读取assets中的文件数据

assets目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制

用于储存较小的文件,可以有目录结构,也就是assets目录下可以再建立文件夹

assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类,即不可使用R.id.fileName进行访问

创建assets文件夹

在项目结构管理区,选择project视图,在app/src/main文件夹下,新建assets文件夹

在项目底部根目录下的xxx.iml文件中进行配置(xxx为项目工程名)

在configuration 标签下,添加option子标签

通过getResource()或AssetsManager的getAssets()方法获取字节流,而后通过文件的一般读取方式进行读取。

//通过getAssets获取InputStream获取字节流

InputStream is = getResources().getAssets().open("info.txt");

//将字节流转换为字符流

InputStreamReader isr =newInputStreamReader(is,"UTF-8");

//创建带缓冲区的字符流

BufferedReader bfr =newBufferedReader(isr);

//逐行循环读取文件

String in ="";

while((in = bfr.readLine()) !=null){

Log.i(TAG,in);

}

三、读取raw文件夹中的文件数据

assets目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制

res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;

创建raw目录,在res目录下创建raw目录,将文件储存在目录中

通过getResource.openRawResource()将文件读取为字节流,由于文件被影射到R.java文件中,所以参数可以直接使用R.raw.info,而后按照正常的文件读写方式读写

InputStream is = getResources().openRawResource(R.raw.info);

InputStreamReader isr =newInputStreamReader(is);

BufferedReader bfr =newBufferedReader(isr);

String in ="";

try{

while((in = bfr.readLine()) !=null){

Log.i(TAG,in);

}

四、读取内部(internal storage)储存的文件数据

程序运行后,在当前应用下的data->data->应用目录下的储存空间为文件内部储存空间包含cache和code_cache,只对当前应用可见。使用OpenFileOutput(filename,写入模式)方法,可以在应用内部储存中自动创建files文件夹,在files文件夹中,创建相应文件名的文件。

读取数据:程序从输入流读取数据,数据源为键盘,网络,文件等。

写入数据:程序向输出流写入数据,将程序中的数据输出到显示器,文件,网络

写入数据:调用OpenFileOutput(filename,写入模式)方法,得到FileOutputStream,包装成OutputStreamWriter,然后调用write方法进行写入,冲刷缓冲区,关闭流

//文件输出流,第二个参数为写入模式,使用openFileOutPut()方法输出的文件在

//应用程序内部储存空间

FileOutputStream fos = openFileOutput(flieName,Context.MODE_PRIVATE);

//将文件输出流进一步包装,变为可写入字符串的OutPutStreamWriter

OutputStreamWriter osw =newOutputStreamWriter(fos,"UTF-8");

osw.write(et.getText().toString());

//执行flush操作,将缓冲区的数据全部输出

osw.flush();

fos.flush();

//关闭流,后打开的流先关闭

osw.close();

fos.close();

Toast.makeText(MainActivity.this,"写入完成",Toast.LENGTH_SHORT).show();

读取数据:调用OpenFileInput(filename)方法,得到FileInputStream,包装成InputStreamReader,创建字符数组,然后调用read方法进行读取,没有冲刷缓冲区。记得关闭流,可将字符数组转换为 String

//openFileInput()只有一个参数,即需要读取的文件名

FileInputStream fis = openFileInput(flieName);

//包装成为InputStreamReader,可调用read方法

InputStreamReader isr =newInputStreamReader(fis,"UTF-8");

//创建字符数组,通过fis.available()获取字符流中可用字符的长度

charinput[] =new char[fis.available()];

//将字符流读入字符数组

isr.read(input);

isr.close();

fis.close();

//将字符数组转为String

String text =newString(input);

//将string设置为TextView的内容

tv.setText(text);

五、读取外部储存(external storage)的文件数据

外部储存类似 sd card,一些设备将"internal" 与 "external" 都做成了不可卸载的内置存储,虽然如此,但是这一整块还是从逻辑上有被划分为"internal"与”external”.

Internal storage:

总是可用的

这里的文件默认只能被我们的app所访问。

当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。

Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。

External storage:

并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。

是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。

当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。

External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。尽管app是默认被安装到internal storage的,我们还是可以通过在程序的manifest文件中声明android:installLocation属性来指定程序安装到external storage。

获取external storage权限:写入权限需要在Manifest文件中添加

读取权限默认目前默认拥有,为确保准确可以声明

当声明拥有写入外部储存权限时,自动拥有读取外部储存的权限

使用Environment.getExternalStorageDirectory()获取系统SD卡路径

当最小sdk小于23时,虽然在manifest文件中声明了权限。应用启动时需要仍需要请求使用外部储存。设置判断是否请求权限与请求权限的函数

//判断是否请求外部储存权限

protected booleanshouldAskPermissions() {

return(Build.VERSION.SDK_INT> Build.VERSION_CODES.LOLLIPOP_MR1);

}

//当最小sdk小于23时,请求外部储存权限

@TargetApi(23)

protected voidaskPermissions() {

String[] permissions = {

"android.permission.READ_EXTERNAL_STORAGE",

"android.permission.WRITE_EXTERNAL_STORAGE"

};

intrequestCode =200;

requestPermissions(permissions,requestCode);

}

在onCreate函数中进行调用

External storage对其他应用与用户可访问修改,其中文件分为两类:public private

public:对其他用户有用,应用卸载时应保留,例如下载的文件,拍摄的照片,保存的音乐

private:虽然技术上可以访问,但对其他应用无用,应用卸载时自动删除,主要为缓存

储存在public时,使用getExternalStoragePublicDirectory()方法,参数为特定的文件类型

通过Environment.Directory获得

//定义一个储存在ExternalStorage的public的文件,参数必须为特定的文件类型:DIRECTORY_MUSIC 或者 DIRECTORY_PICTURES

Filesdcard= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

储存在private时,使用getExternalStorageDirectory()方法,指定文件类型参数会储存在private的参数文件夹下,不指定类型,储存在private根目录下

//在外部储存private的根目录下新建文件夹pictures

StringfilePath= Environment.getExternalStorageDirectory()+"/Pictures”;

获取路径后,按正常文件操作读写

写入操作:

// 判断设备sd卡是否存在

if(!sdcard.exists()){

Toast.makeText(getApplicationContext(),"sd卡不存在",Toast.LENGTH_SHORT).show();

return;

}

//文件不存在创建文件

if(!myFile.exists()){

try{

myFile.createNewFile();

}catch(IOException e) {

Log.e("文件创建失败",e.getMessage());

e.printStackTrace();

}

//文件写入操作

try{

FileOutputStream fos =newFileOutputStream(myFile);

OutputStreamWriter osw =newOutputStreamWriter(fos);

osw.write(et.getText().toString());

osw.flush();

fos.flush();

osw.close();

fos.close();

Toast.makeText(getApplicationContext(),"数据写入成功",Toast.LENGTH_SHORT).show();

}catch(FileNotFoundException e) {

Log.e("文件没找到",e.getMessage());

e.printStackTrace();

}catch(IOException e) {

Log.e("io错误",e.getMessage());

e.printStackTrace();

}

读取操作:

// 判断设备sd卡是否存在

if(!sdcard.exists()){

Toast.makeText(getApplicationContext(),"sd卡不存在",Toast.LENGTH_SHORT).show();

return;

}

//文件不存在创建文件

if(!myFile.exists()) {

try{

myFile.createNewFile();

}catch(IOException e) {

e.printStackTrace();

}

try{

FileInputStream fis =newFileInputStream(myFile);

InputStreamReader isr =newInputStreamReader(fis);

BufferedReader br =newBufferedReader(isr);

//StringBuilder储存所有数据

StringBuilder strBuilder =newStringBuilder();

//临时变量储存每行数据

String line ="";

while((line = br.readLine()) !=null) {

//不为空,不断追加

strBuilder.append(line);

}

br.close();

isr.close();

fis.close();

Toast.makeText(MainActivity.this,"数据读取成功",Toast.LENGTH_SHORT).show();

tv.setText(strBuilder);

}catch(FileNotFoundException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容