Android文件读写操作
2015-06-08 15:54
423 查看
一、概要
本节主要介绍android几种文件的读写方式,主要包括资源文件、内部存储区文件、外部存储区文件。
1、资源文件:
apk中有两种资源文件,raw下的和assets下的,这些数据只能读取,不能写入。更重要的是该目录下的文件大小不能超过1M。
2、内部存储:
总是可用的
这里的文件默认是只能被你的app所访问的。
当用户卸载你的app的时候,系统会把internal里面的相关文件都清除干净。
Internal是在你想确保不被用户与其他app所访问的最佳存储区域。
3、 外部存储:
并不总是可用的,因为用户可以选择把这部分作为USB存储模式,这样就不可以访问了。
是大家都可以访问的,因此保存到这里的文件是失去访问控制权限的。
当用户卸载你的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在你不需要严格的访问权限并且你希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
二、读写方式
1.资源文件(只读)
*res/raw和assets的相同点:
(1)两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
*res/raw和assets的不同点:
(1)res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
(2)res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹。
(3)读取方式
raw使用InputStreamin = getResources().openRawResource(R.raw.test);
asset使用InputStreamin = getResources().getAssets().open(fileName);
注:在使用InputStream的时候会抛出IOException,需在函数头部加上throws IOException或在使用时用try
catch语句捕获。
raw资源文件读取:
assets资源文件读取:
2.内部存储区文件(/data/data/<应用程序名>目录上的文件)
(1)存储区
方式一(openFileOutput):
<1>写操作:FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE);
<2>读操作:FileInputStream fin = openFileInput(fileName);
<3>写操作中的使用模式:
MODE_APPEND:即向文件尾写入数据
MODE_PRIVATE:即仅打开文件可写入数据
MODE_WORLD_READABLE:所有程序均可读该文件数据
MODE_WORLD_WRITABLE:即所有程序均可写入数据。
数据区写入:
数据区读取:
方式二(getFileDir()):
Log.d("TAG", "file1=" + file1.getAbsolutePath()); try { OutputStream outputStream1 = new FileOutputStream(file1); outputStream1.write(writestr.getBytes());
outputStream1.close(); } catch (Exception e) { e.printStackTrace(); }
以上方法在需要的地方调用即可,方法二和方法一实现的效果一样,读取方法与前面类似,已略。。
(2)缓存区
getCacheDir() 通过此方法可以获取到你的APP内部存储的文件,路径为/data/data/package_name/cache。
此方法,程序调用时传入的fileName为“cache.txt”,writestr内容为“cache”,内部存储存储位置如下图所示
内部存储在你的APP卸载的时候,会一块被删除,因此,我们可以在cache目录里面放置我们的图片缓存,而且cache与files的差别在于,如果手机的内部存储控件不够了,会自行选择cache目录进行删除,因此,不要把重要的文件放在cache文件里面,可以放置在files里面,因为这个文件只有在APP被卸载的时候才会被删除。还有要注意的一点是,如果应用程序是更新操作,内部存储不会被删除,区别于被用户手动卸载。
3.外部存储区域文件
(1)外部公共区域
<1>读操作
FileInputStream fin = new FileInputStream(fileName);
<2>写操作
FileOutputStream fout = new FileOutputStream(fileName);
<3>必要步骤
①获取权限
A 获取文件修改权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
B可写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
②检查内存状态(是否安装sd卡)
if(Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED))
③读写操作
SD卡写入数据:
SD卡读取数据:
以上文件存储在sdcard中fileDemo文件夹下
注意:关于sdcard,访问SDCard必须在AndroidManifest.xml中加入访问SDCard的权限
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir =Environment.getExternalStorageDirectory();//获取SDCard目录
File saveFile = new File(sdCardDir,“a.txt”);
FileOutputStream outStream = newFileOutputStream(saveFile);
outStream.write(“test”.getBytes());
outStream.close();
}
Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。
Environment.getExternalStorageDirectory()方法用于获取SDCard的目录。
另外,可以使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,getExternalStoragePublicDirectory()在运行的时候,会需要你带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC
或者 DIRECTORY_PICTURES. 如下:
(2)外部私有存储
从上面内部存储的介绍来看,内部存储的文件应该属于私有文件,别的APP想要访问是比较困难的,那么外部存储呢?外部存储由于容量较大,一般是我们的APP保存较大文件的不二选择,那么是不是外部存储里面的文件,所有的APP都可以随意访问呢?显然并不是这样的,在外部存储中,也存在着私有文件的概念。
就像我们在前面获取内部存储方法一样,我们使用Context.getExternalCacheDir()和Context.getExternalFilesDir()就可以获取到外部存储的私有文件,我们以下面的代码为例
最后,不管你是使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,还是使用 getExternalFilesDir() 来储存那些对与你的app来说是私有的文件,有一点很重要,那就是你要使用那些类似DIRECTORY_PICTURES
的API的常量。那些目录类型参数可以确保那些文件被系统正确的对待。例如,那些以DIRECTORY_RINGTONES 类型保存的文件就会被系统的media scanner认为是ringtone而不是音乐。
下面就是这些参数对应的文件夹
本文参考http://blog.csdn.net/zhaokaiqiang1992。
本节主要介绍android几种文件的读写方式,主要包括资源文件、内部存储区文件、外部存储区文件。
1、资源文件:
apk中有两种资源文件,raw下的和assets下的,这些数据只能读取,不能写入。更重要的是该目录下的文件大小不能超过1M。
2、内部存储:
总是可用的
这里的文件默认是只能被你的app所访问的。
当用户卸载你的app的时候,系统会把internal里面的相关文件都清除干净。
Internal是在你想确保不被用户与其他app所访问的最佳存储区域。
3、 外部存储:
并不总是可用的,因为用户可以选择把这部分作为USB存储模式,这样就不可以访问了。
是大家都可以访问的,因此保存到这里的文件是失去访问控制权限的。
当用户卸载你的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
External是在你不需要严格的访问权限并且你希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。
二、读写方式
1.资源文件(只读)
*res/raw和assets的相同点:
(1)两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。
*res/raw和assets的不同点:
(1)res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
(2)res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹。
(3)读取方式
raw使用InputStreamin = getResources().openRawResource(R.raw.test);
asset使用InputStreamin = getResources().getAssets().open(fileName);
注:在使用InputStream的时候会抛出IOException,需在函数头部加上throws IOException或在使用时用try
catch语句捕获。
raw资源文件读取:
/** * 读取raw资源文件下的文件 * @throws IOException */ private void getRawResource() { String result=""; try { //得到资源中的Raw数据流 InputStream in = getResources().openRawResource(R.raw.test); //得到数据的大小 int length = in.available(); //文件大小的byte数组 byte [] buffer = new byte[length]; //读取数据到byte数组 in.read(buffer); //转成string格式,依test.txt的编码类型选择合适的编码,如果不调整会乱码 result = EncodingUtils.getString(buffer, "GBK"); //关闭 流 in.close(); Log.i("TAG", "rawResource:"+result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
assets资源文件读取:
/** * 读取assets资源文件下的文件 * @param fileName 文件名 */ private void getAssertResource(String fileName) { String res=""; try { // \Test\assets\filename这里有这样的文件存在 InputStream in = getResources().getAssets().open(fileName); int length = in.available(); byte [] buffer = new byte[length]; in.read(buffer); res = EncodingUtils.getString(buffer, "GBK"); Log.i("TAG", "assertResource:"+res); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
2.内部存储区文件(/data/data/<应用程序名>目录上的文件)
(1)存储区
方式一(openFileOutput):
<1>写操作:FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE);
<2>读操作:FileInputStream fin = openFileInput(fileName);
<3>写操作中的使用模式:
MODE_APPEND:即向文件尾写入数据
MODE_PRIVATE:即仅打开文件可写入数据
MODE_WORLD_READABLE:所有程序均可读该文件数据
MODE_WORLD_WRITABLE:即所有程序均可写入数据。
数据区写入:
/** * 往/data/data/<应用程序名>目录上写入文件 */ public void writeFile(String fileName,String writestr) { try { /*创建带文件名和操作模式的文件输出流 * MODE_APPEND:即向文件尾写入数据 MODE_PRIVATE:即仅打开文件可写入数据 MODE_WORLD_READABLE:所有程序均可读该文件数据 MODE_WORLD_WRITABLE:即所有程序均可写入数据。 */ FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE); //获得文件大小 byte [] bytes = writestr.getBytes(); //写入 fout.write(bytes); //关闭流 fout.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
数据区读取:
/** * 从/data/data/<应用程序名>目录/files 上读取文件 */ public String readFile(String fileName){ String res=""; try{ FileInputStream fin = openFileInput(fileName); int length = fin.available(); byte [] buffer = new byte[length]; fin.read(buffer); res = EncodingUtils.getString(buffer, "UTF-8"); fin.close(); } catch(Exception e){ e.printStackTrace(); } return res; }
方式二(getFileDir()):
<span style="font-size:18px;"><span style="font-weight: bold;"></span></span><pre name="code" class="java">public void writeFile1(String fileName,String writestr)File file1 = new File(getFilesDir(),fileName);
Log.d("TAG", "file1=" + file1.getAbsolutePath()); try { OutputStream outputStream1 = new FileOutputStream(file1); outputStream1.write(writestr.getBytes());
outputStream1.close(); } catch (Exception e) { e.printStackTrace(); }
以上方法在需要的地方调用即可,方法二和方法一实现的效果一样,读取方法与前面类似,已略。。
(2)缓存区
getCacheDir() 通过此方法可以获取到你的APP内部存储的文件,路径为/data/data/package_name/cache。
public void writeCache(String fileName,String writestr) { File file2 = new File(getCacheDir(), fileName); Log.d("TAG", "file2=" + file2.getAbsolutePath()); try { OutputStream outputStream1 = new FileOutputStream(file2); outputStream1.write(writestr.getBytes()); outputStream1.close(); } catch (Exception e) { e.printStackTrace(); } }
此方法,程序调用时传入的fileName为“cache.txt”,writestr内容为“cache”,内部存储存储位置如下图所示
内部存储在你的APP卸载的时候,会一块被删除,因此,我们可以在cache目录里面放置我们的图片缓存,而且cache与files的差别在于,如果手机的内部存储控件不够了,会自行选择cache目录进行删除,因此,不要把重要的文件放在cache文件里面,可以放置在files里面,因为这个文件只有在APP被卸载的时候才会被删除。还有要注意的一点是,如果应用程序是更新操作,内部存储不会被删除,区别于被用户手动卸载。
3.外部存储区域文件
(1)外部公共区域
<1>读操作
FileInputStream fin = new FileInputStream(fileName);
<2>写操作
FileOutputStream fout = new FileOutputStream(fileName);
<3>必要步骤
①获取权限
A 获取文件修改权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
B可写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
②检查内存状态(是否安装sd卡)
if(Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED))
③读写操作
SD卡写入数据:
/** * 向SD卡写入文件 * @param fileName 文件名 * @param write_str 要写入的字符串 * @throws IOException */ public void writeFileSdcardFile(String fileName,String write_str) { try{ /**路径设为sdcard/fileDemo, * Environment.getExternalStorageDirectory()方法获取内存卡地址 */ File dir=new File(Environment.getExternalStorageDirectory()+"/fileDemo"); if (!dir.exists()) dir.mkdirs(); File file=new File(dir, fileName); //创建带文件名的文件输出流 FileOutputStream fout = new FileOutputStream(file); //获得大小 byte [] bytes = write_str.getBytes(); //写入 fout.write(bytes); //关闭流 fout.close(); } catch(Exception e){ e.printStackTrace(); } }
SD卡读取数据:
/** * 读sd取卡中的文件 * @param fileName 文件名 * @return 文件中的内容 * @throws IOException */ public String readFileSdcardFile(String fileName){ String res=""; try{ File dir=new File(Environment.getExternalStorageDirectory()+"/fileDemo"); File file=new File(dir, fileName); //文件输入流 FileInputStream fin = new FileInputStream(file); //获得文件大小 int length = fin.available(); //文件大小的byte数组 byte [] buffer = new byte[length]; //将文件内容读入byte数组 fin.read(buffer); //转成字符串格式 res = EncodingUtils.getString(buffer, "UTF-8"); Log.i("TAG", "读sd卡文件:"+res); //关闭流 fin.close(); } catch(Exception e){ e.printStackTrace(); } return res; }
以上文件存储在sdcard中fileDemo文件夹下
注意:关于sdcard,访问SDCard必须在AndroidManifest.xml中加入访问SDCard的权限
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir =Environment.getExternalStorageDirectory();//获取SDCard目录
File saveFile = new File(sdCardDir,“a.txt”);
FileOutputStream outStream = newFileOutputStream(saveFile);
outStream.write(“test”.getBytes());
outStream.close();
}
Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。
Environment.getExternalStorageDirectory()方法用于获取SDCard的目录。
另外,可以使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,getExternalStoragePublicDirectory()在运行的时候,会需要你带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC
或者 DIRECTORY_PICTURES. 如下:
public File getAlbumStorageDir(Context context, String albumName) { // Get the directory for the app's private pictures directory. File file = new File(context.getExternalFilesDir( Environment.DIRECTORY_PICTURES), albumName); if (!file.mkdirs()) { Log.e(LOG_TAG, "Directory not created"); } return file; }
(2)外部私有存储
从上面内部存储的介绍来看,内部存储的文件应该属于私有文件,别的APP想要访问是比较困难的,那么外部存储呢?外部存储由于容量较大,一般是我们的APP保存较大文件的不二选择,那么是不是外部存储里面的文件,所有的APP都可以随意访问呢?显然并不是这样的,在外部存储中,也存在着私有文件的概念。
就像我们在前面获取内部存储方法一样,我们使用Context.getExternalCacheDir()和Context.getExternalFilesDir()就可以获取到外部存储的私有文件,我们以下面的代码为例
File file3 = new File(getExternalCacheDir().getAbsolutePath(), "getExternalCacheDir.txt"); try { OutputStream outputStream1 = new FileOutputStream(file3); outputStream1.write("getExternalCacheDir".getBytes()); outputStream1.close(); } catch (Exception e) { e.printStackTrace(); } Log.d("TAG", "file3=" + file3); File file4 = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "getExternalFilesDir.txt"); try { OutputStream outputStream1 = new FileOutputStream(file4); outputStream1.write("getExternalFilesDir".getBytes()); outputStream1.close(); } catch (Exception e) { e.printStackTrace(); }系统中外部私有存储位置如下图所示:
最后,不管你是使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,还是使用 getExternalFilesDir() 来储存那些对与你的app来说是私有的文件,有一点很重要,那就是你要使用那些类似DIRECTORY_PICTURES
的API的常量。那些目录类型参数可以确保那些文件被系统正确的对待。例如,那些以DIRECTORY_RINGTONES 类型保存的文件就会被系统的media scanner认为是ringtone而不是音乐。
下面就是这些参数对应的文件夹
本文参考http://blog.csdn.net/zhaokaiqiang1992。
相关文章推荐
- android:padding和android:layout_margin的区别?
- Android 高级Drawable资源---复合Drawable----层Drawable
- Android中的AlarmManager的使用
- android google服务框架安装
- Android Studio 导入so
- Android Studio: Android Manifest doesn't exists or has incorrect root tag
- [Selenium] Android HTML5 中 Application Cache
- Android 控件之ProgressBar进度条
- pc android sqlcipher 加密
- android setContentView() 、LayoutInflater的区别
- Android中如何使用Cursor遍历Sqlite
- ListView的相关研究(一)
- Android raw to bmp
- [Selenium] Android HTML5 中 Web Storage
- Android OnMeasure
- android Path类
- [Android] 使用JSON和SharedPreferences存储用户自定义类
- android实习期日常笔记(一)
- at android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:)
- [Android开发] Android应用与开发环境