Android学习之文件存储读取
前言
相信大家都知道知道,在androidos中,提供了五中数据存储方式,分别是:contentprovider存储、文件存储、sharedpreference存储、sqlite数据库存储、网络存储。那么这一篇,我们介绍文件存储。
1.android文件的操作模式
学过java的同学都知道,我们新建文件,然后就可以写入数据了,但是android却不一样,因为android是 基于linux的,我们在读写文件的时候,还需加上文件的操作模式,android中的操作模式如下:
2、文件的操作模式
我们在学java的时候都知道,java中的io操作来进行文件的保存和读取,android是基于linux的,与java不同的是android在context类中封装好了输入流和输出流的获取方法,分别是: fileinputstream openfileinput(string name); fileoutputstream(string name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。android提供的文件模式有:
1.mode_private:android提供的默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。
2.mode_append:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
3.mode_world_readable:表示当前文件可以被其他应用读取;
4.mode_world_writeable:表示当前文件可以被其他应用写入。
此外,android还提供了其它几个重要的文件操作的方法:
1.getdir(string name , int mode):在应用程序的数据文件夹下获取或者创建name对应的子目录
2.file getfilesdir():获取app的data目录下的绝对路径
3.string[] filelist():返回app的data目录下数的全部文件
4.deletefile(string filename):删除app的data目录下的指定文件
3、读写文件
android的读写文件和java一样,也是一样通过io操作实现,下面我们通过一个简单的例子走一下这个流程:
布局文件代码:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <edittext android:id="@+id/ed_file_save" android:layout_width="match_parent" android:layout_height="wrap_content" /> <button android:id="@+id/btn_file_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:text="保存内容" /> <button android:id="@+id/btn_file_read" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:text="读取内容" /> <textview android:id="@+id/tv_read_file" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:textcolor="#000" android:textsize="14sp" /> </linearlayout>
activity代码:
package com.example.datasave; import android.content.context; import android.os.bundle; import android.support.annotation.nullable; import android.support.v7.app.appcompatactivity; import android.view.view; import android.widget.button; import android.widget.edittext; import android.widget.textview; import java.io.fileinputstream; import java.io.fileoutputstream; import java.io.ioexception; /** * created by devin on 2016/7/19. */ public class filedataactivity extends appcompatactivity { private edittext ed_file_save; private button btn_file_save; private button btn_file_read; private textview tv_read_file; private string filename = " hello.txt"; @override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_file); ed_file_save = (edittext) findviewbyid(r.id.ed_file_save); btn_file_save = (button) findviewbyid(r.id.btn_file_save); btn_file_read = (button) findviewbyid(r.id.btn_file_read); tv_read_file = (textview) findviewbyid(r.id.tv_read_file); btn_file_save.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { string filecontent = ed_file_save.gettext().tostring(); try { save(filecontent); toastutils.showtoast(filedataactivity.this, "文件写入成功"); } catch (exception e) { e.printstacktrace(); toastutils.showtoast(filedataactivity.this, "文件写入失败"); } } }); btn_file_read.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { try { string content = read(); tv_read_file.settext("文件的内容是:" + content); } catch (ioexception e) { e.printstacktrace(); toastutils.showtoast(filedataactivity.this, "读取文件失败!"); } } }); } public void save(string filecontent) throws exception { fileoutputstream output = this.openfileoutput(filename, context.mode_private); output.write(filecontent.getbytes()); output.close(); } public string read() throws ioexception { //打开文件输入流 fileinputstream input = this.openfileinput(filename); byte[] temp = new byte[1024]; stringbuffer stringbuffer = new stringbuffer(""); int len = 0; while ((len = input.read(temp)) > 0) { stringbuffer.append(new string(temp, 0, len)); } //关闭输入流 input.close(); return stringbuffer.tostring(); } }
最后是实现效果图:
这里文件使用的模式是私有模式,只能本应用读取还会覆盖原文件,这样就可以实现简单的文件读写。
4、读写sdcard的文件
读写sdcard需要权限:
<uses-permission android:name="android.permission.mount_unmount_filesystems" /> <uses-permission android:name="android.permission.write_external_storage" />
对设备读写sdcard的时候需要判断sdcard是否存在,很多手机是不存在sdcard的,下面我们对sdcard的读写中会有体现,下面我们一起通过例子实现sdcard的读写操作
首先是布局文件代码:
<edittext android:id="@+id/ed_file_save_sd" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="20dp" /> <button android:id="@+id/btn_file_save_sd" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:text="写入到sdcard" /> <button android:id="@+id/btn_file_read_sd" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:text="从sdcard读取" /> <textview android:id="@+id/tv_read_file_sd" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margintop="10dp" android:textcolor="#000" android:textsize="14sp" />
activity代码:
ed_file_save_sd = (edittext) findviewbyid(r.id.ed_file_save_sd); tv_read_file_sd = (textview) findviewbyid(r.id.tv_read_file_sd); btn_file_read_sd = (button) findviewbyid(r.id.btn_file_read_sd); btn_file_read_sd.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { try { string content = readfromsd(); tv_read_file_sd.settext("从sdcard读取到的内容是:" + content); } catch (exception e) { e.printstacktrace(); toastutils.showtoast(filedataactivity.this, "读取文件失败!"); } } }); btn_file_save_sd = (button) findviewbyid(r.id.btn_file_save_sd); btn_file_save_sd.setonclicklistener(new view.onclicklistener() { @override public void onclick(view view) { string content = ed_file_save_sd.gettext().tostring(); try { save2sdcard(content); toastutils.showtoast(filedataactivity.this, "文件写入sdcard成功"); } catch (exception e) { e.printstacktrace(); toastutils.showtoast(filedataactivity.this, "文件写入sdcard失败"); } } }); public void save2sdcard(string content) throws exception { if (environment.getexternalstoragestate().equals(environment.media_mounted)) { // 如果sdcard存在 string filename3 = environment.getexternalstoragedirectory().getcanonicalpath() + file.separator + "test" + file.separator + filename2; file file = new file(filename3); if (!file.getparentfile().exists()) { file.getparentfile().mkdir(); } fileoutputstream fileoutputstream = new fileoutputstream(file); fileoutputstream.write(content.getbytes()); fileoutputstream.close(); } else { toastutils.showtoast(this, "sdcard不存在"); } } public string readfromsd() throws exception { stringbuffer stringbuffer = new stringbuffer(""); if (environment.getexternalstoragestate().equals(environment.media_mounted)) { string filename3 = environment.getexternalstoragedirectory().getcanonicalpath() + file.separator + "test" + file.separator + filename2; file file = new file(filename3); if (!file.getparentfile().exists()) { file.getparentfile().mkdir(); } fileinputstream fileinputstream = new fileinputstream(file); byte[] temp = new byte[1024]; int len = 0; while ((len = fileinputstream.read(temp)) > 0) { stringbuffer.append(new string(temp, 0, len)); } fileinputstream.close(); } else { toastutils.showtoast(this, "sdcard不存在"); } return stringbuffer.tostring(); }
sdcard的读取和文件操作差不多,需要判断sdcard是否存在,最后是效果图:
5、读取raw和assets文件的数据
raw/res中的文件会被映射到android的r文件中,我们直接通过r文件就可以访问,这里就不在过多介绍了。
assets中的文件不会像raw/res中的文件一样被映射到r文件中,可以有目录结构,android提供了一个访问assets文件的assetmanager对象,我们访问也很简单:
assetmanager assetsmanager = getassets(); inputstream inputstream = assetsmanager.open("filename");
这样就可以直接获取到assets目录下的资源文件。
androidos的文件存储就简单介绍到这里,下面提供一些文件存储的工具方法:
package com.example.datasave.io; import android.content.context; import java.io.bufferedreader; import java.io.bufferedwriter; import java.io.bytearrayoutputstream; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.fileoutputstream; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.io.outputstreamwriter; /** * io流 工具类<br> * 很简单,仅支持文本操作 */ public class ioutils { /** * 文本的写入操作 * * @param filepath 文件路径。一定要加上文件名字 <br> * 例如:../a/a.txt * @param content 写入内容 * @param append 是否追加 */ public static void write(string filepath, string content, boolean append) { bufferedwriter bufw = null; try { bufw = new bufferedwriter(new outputstreamwriter( new fileoutputstream(filepath, append))); bufw.write(content); } catch (exception e1) { e1.printstacktrace(); } finally { if (bufw != null) { try { bufw.close(); } catch (ioexception e) { e.printstacktrace(); } } } } /** * 文本的读取操作 * * @param path 文件路径,一定要加上文件名字<br> * 例如:../a/a.txt * @return */ public static string read(string path) { bufferedreader bufr = null; try { bufr = new bufferedreader(new inputstreamreader( new fileinputstream(path))); stringbuffer sb = new stringbuffer(); string str = null; while ((str = bufr.readline()) != null) { sb.append(str); } return sb.tostring(); } catch (exception e) { e.printstacktrace(); } finally { if (bufr != null) { try { bufr.close(); } catch (ioexception e) { e.printstacktrace(); } } } return null; } /** * 文本的读取操作 * * @param is 输入流 * @return */ public static string read(inputstream is) { bufferedreader bufr = null; try { bufr = new bufferedreader(new inputstreamreader(is)); stringbuffer sb = new stringbuffer(); string str = null; while ((str = bufr.readline()) != null) { sb.append(str); } return sb.tostring(); } catch (exception e) { e.printstacktrace(); } finally { if (bufr != null) { try { bufr.close(); } catch (ioexception e) { e.printstacktrace(); } } } return null; } /** * @param context 上下文 * @param filename 文件名 * @return 字节数组 */ public static byte[] readbytes(context context, string filename) { fileinputstream fin = null; byte[] buffer = null; try { fin = context.openfileinput(filename); int length = fin.available(); buffer = new byte[length]; fin.read(buffer); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { try { if (fin != null) { fin.close(); fin = null; } } catch (ioexception e) { e.printstacktrace(); } } return buffer; } /** * 快速读取程序应用包下的文件内容 * * @param context 上下文 * @param filename 文件名称 * @return 文件内容 * @throws ioexception */ public static string read(context context, string filename) throws ioexception { fileinputstream instream = context.openfileinput(filename); bytearrayoutputstream outstream = new bytearrayoutputstream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = instream.read(buffer)) != -1) { outstream.write(buffer, 0, len); } byte[] data = outstream.tobytearray(); return new string(data); } }
好的,关于android的数据存储与访问的文件读写就到这里,如果在学习本文中遇到什么问题,或者觉得有些纰漏的地方,欢迎提出,万分感激,谢谢~
下一篇: Python实现图片转字符画的示例代码