一、分类

文件读写作为Android四大数据存储方式之一,又分为内部存储和外部存储两种:

(1)内部存储(Internal storage):

  1. 总是可用。
  2. 文件默认情况存储在/data/data/包名/files,缓存文件存储在/data/data/包名/cache中,默认情况下只能只能被本APP操作,当然可以在openFileOutput()中指定是否可被其他app读写。
  3. 当使用者卸载你的app时,系统会自动从内部存储中删除安排app的所有文件。

(2)外部存储(External storage):

  1.并不是总是可用,因为用户有可能将SD卡作为USB存储挂载或者在某些情况下将SD卡从设备上卸下,因此需要使用getExternalStorageState()来查询外部存储的状态,当返回的状态是MEDIA_MOUNTED时才能读写。

  2.保存在外部存储的文件是world-readable的,所以保存在外部存储的文件可能被其他应用读取。

  3.当用户卸载app时,只用当你调用getExternalFilesDir()来保存文件时系统才会从外部存储中移除app的文件。

  4.权限:

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  向SD卡写入数据权限,隐式授予了读取权限

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

  当app只需要读取而非写入权限的时候更适合使用该权限

  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

  在SD卡中创建和删除文件权限

二、方法介绍

  1)getFilesDir():返回/data/data/包名/files

  2)getCacheDir():返回/data/data/包名/cache,在确定缓存文件不再需要时删除掉,为app使用的内存量实现一个合理的大小限制,比如1M。如果系统在存储空间低的时候运行,可能会在没有警告的时候删除缓存文件。

  3)FileInputStream openFileInput(String name):打开应用程序文件夹下的nam文件对应的输入流。

  4)FileOutputStream openFileOutput(String name,int mode):打开应用程序文件夹下的nam文件对应的输出流(若文件不存在则创建),第二个参数指定打开文件的模式:

    MODE_PRIVATE:该文件只能被当前程序读写

    MODE_APPEND:已追加方式打开该文件

    MODE_WORLD_READABLE:该文件可被其他程序读取

    MODE_WORLD_WRITEABLE:该文件可被其他程序读写

  5)getDir(String name,int mode):在应用程序的数据文件夹下获取或创建app_name对应的子目录

    第二个参数:     

    MODE_PRIVATE:默认模式,该文件只能被当前程序访问

    MODE_WORLD_READABLE:该文件可被其他程序访问(在API17被弃用)

    MODE_WORLD_WRITEABLE:该文件可被其他程序读写(在API17被弃用)

  6)String[] fileList():返回应用程序的数据文件夹下的全部文件名

  7)deleteFile(String name):删除应用程序的数据文件夹下指定文件

  8)Environment.getExternalStorageState():判断手机是否插入SD卡,当返回MEDIA_MOUNTED时才能对其进行读写

  9)getExternalStorageDirectory():返回SD卡的根目录  /storage/emulated/0

  10)getExternalStoragePublicDirectory(String type):在SD卡的根目录创建一个由type指定的特定类型的文件夹

  例如:/storage/emulated/0/Pictures

  11)getExternalFilesDir(String type):在SD卡中对应应用的数据文件夹中创建一个由type指定的特定类型的文件夹

  例如:storage/emulated/0/Android/data/应用包名/files/Pictures

  type可选项:

    DIRECTORY_MUSIC 标准音乐目录,

    DIRECTORY_PODCASTS ,

    DIRECTORY_RINGTONES 铃声,

    DIRECTORY_ALARMS 警报音,

    DIRECTORY_NOTIFICATIONS 通知音,

    DIRECTORY_PICTURES 图片,

    DIRECTORY_MOVIES 电影,

      DIRECTORY_DOWNLOADS 下载,

    DIRECTORY_DCIM 由camera拍摄的照片和视频存放目录

  TIPS:(1)需要注意的是getExternalStoragePublicDirectory()与getExternalFilesDir()的区别在于前者所创建的文件不会在用户卸载被系统删除,而后者在SD卡创建的应用程序数据文件会被系统删除。

     (2)当用户卸载APP的时候系统会删除所有在内部存储中对应APP的文件以及由getExternalFilesDir()调用创建的文件。

三、代码示例

内部存储:

  1. import android.content.Context;
  2. import android.support.v7.app.AppCompatActivity;
  3. import android.os.Bundle;
  4. import android.util.Log;
  5. import android.view.View;
  6. import android.widget.Button;
  7. import android.widget.EditText;
  8.  
  9. import java.io.FileInputStream;
  10. import java.io.FileNotFoundException;
  11. import java.io.FileOutputStream;
  12. import java.io.IOException;
  13.  
  14. public class MainActivity extends AppCompatActivity {
  15.  
  16. final String FILE_NAME="test.txt";
  17. @Override
  18. protected void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.activity_main);
  21. Button read= (Button) findViewById(R.id.read);
  22. final Button write= (Button) findViewById(R.id.write);
  23. final EditText editText= (EditText) findViewById(R.id.edit_area);
  24. write.setOnClickListener(new View.OnClickListener() {
  25. @Override
  26. public void onClick(View v) {
  27. write(editText.getText().toString());
  28. editText.setText("");
  29. }
  30. });
  31. read.setOnClickListener(new View.OnClickListener() {
  32. @Override
  33. public void onClick(View v) {
  34. editText.setText(read());
  35. }
  36. });
  37. findViewById(R.id.delete).setOnClickListener(new View.OnClickListener() {
  38. @Override
  39. public void onClick(View v) {
  40. delete(FILE_NAME,MainActivity.this);
  41. }
  42. });
  43. }
  44. private String read(){
  45. try {
  46. FileInputStream fis=openFileInput(FILE_NAME);
  47. byte[] buff=new byte[1024];
  48. int hasRead=0;
  49. StringBuffer sb=new StringBuffer();
  50. while ((hasRead=fis.read(buff))>0){
  51. sb.append(new String(buff,0,hasRead));
  52. }
  53. fis.close();
  54. return sb.toString();
  55. } catch (Exception e) {
  56. e.printStackTrace();
  57. }
  58. return null;
  59. }
  60. private void delete(String name,Context context){
  61. context.deleteFile(name);
  62. }
  63. private void write(String content){
  64. try {
  65. FileOutputStream fos=openFileOutput(FILE_NAME,MODE_PRIVATE);
  66. try {
  67. fos.write(content.getBytes());
  68. } catch (IOException e) {
  69. e.printStackTrace();
  70. }
  71. } catch (FileNotFoundException e) {
  72. e.printStackTrace();
  73. }
  74. }
  75. }
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
  3. android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
  4. android:paddingRight="@dimen/activity_horizontal_margin"
  5. android:paddingTop="@dimen/activity_vertical_margin"
  6. android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
  7.  
  8. <EditText
  9. android:id="@+id/edit_area"
  10. android:lines="5"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content" />
  13. <Button
  14. android:id="@+id/read"
  15. android:layout_below="@id/edit_area"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:text="读入"/>
  19. <Button
  20. android:id="@+id/write"
  21. android:layout_toRightOf="@id/read"
  22. android:layout_below="@id/edit_area"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:text="写入"/>
  26. <Button
  27. android:id="@+id/delete"
  28. android:layout_below="@id/edit_area"
  29. android:text="删除"
  30. android:layout_toRightOf="@id/write"
  31. android:layout_width="wrap_content"
  32. android:layout_height="wrap_content" />
  33. </RelativeLayout>

外部存储:

  1. package com.example.administrator.externalfile;
  2.  
  3. import android.content.Context;
  4. import android.os.Environment;
  5. import android.support.v7.app.AppCompatActivity;
  6. import android.os.Bundle;
  7. import android.util.Log;
  8. import android.view.Menu;
  9. import android.view.MenuItem;
  10. import android.view.View;
  11. import android.view.WindowManager;
  12. import android.widget.Button;
  13. import android.widget.EditText;
  14.  
  15. import java.io.File;
  16. import java.io.FileInputStream;
  17. import java.io.IOException;
  18. import java.io.RandomAccessFile;
  19.  
  20. public class MainActivity extends AppCompatActivity {
  21.  
  22. private String TAG="ENTERNAL";
  23. private String FILE_NAME="/test.txt";
  24. @Override
  25. protected void onCreate(Bundle savedInstanceState) {
  26. super.onCreate(savedInstanceState);
  27. setContentView(R.layout.activity_main);
  28. Log.d(TAG, "ExternalStoragePublicDir=" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
  29. Log.d(TAG, "ExternalFilesDir=" + MainActivity.this.getExternalFilesDir(Environment.DIRECTORY_PICTURES));
  30. Log.d(TAG,"ExternalStorageDir="+Environment.getExternalStorageDirectory());
  31. final EditText editText= (EditText) findViewById(R.id.edit_area);
  32. Button read= (Button) findViewById(R.id.read);
  33. final Button write= (Button) findViewById(R.id.write);
  34. read.setOnClickListener(new View.OnClickListener() {
  35. @Override
  36. public void onClick(View v) {
  37. editText.setText(read());
  38. }
  39. });
  40. write.setOnClickListener(new View.OnClickListener() {
  41. @Override
  42. public void onClick(View v) {
  43. write(editText.getText().toString());
  44. editText.setText("");
  45. }
  46. });
  47. }
  48. public boolean isExternalStorageWritable(){
  49. String state= Environment.getExternalStorageState();
  50. if (Environment.MEDIA_MOUNTED.equals(state)){
  51. return true;
  52. }
  53. return false;
  54. }
  55. public boolean isExternalStorageReadable(){
  56. String state=Environment.getExternalStorageState();
  57. if (Environment.MEDIA_MOUNTED.equals(state)||Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
  58. return true;
  59. }
  60. return false;
  61. }
  62.  
  63. /**
  64. * 获取外部公用存储路径
  65. * @param albumName
  66. * @return
  67. */
  68. public File getAlbumStorageDir(String albumName){
  69. File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),albumName);
  70. if (!file.mkdirs()){
  71. Log.d(TAG,"Directory not create");
  72. }
  73. return file;
  74. }
  75.  
  76. /**
  77. * 获取私有外部存储目录
  78. * @param context
  79. * @param albumName
  80. * @return
  81. */
  82. public File getAlbumStorageDir(Context context,String albumName){
  83. File file=new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),albumName);
  84. if (!file.mkdirs()){
  85. Log.d(TAG,"Directory not create");
  86. }
  87. return file;
  88. }
  89. private String read(){
  90. if (isExternalStorageWritable()){
  91. // File sdCard=Environment.getExternalStorageDirectory();
  92. File sdCard=getAlbumStorageDir(MainActivity.this,"test");
  93. try {
  94. FileInputStream fis=new FileInputStream(sdCard.getCanonicalPath()+FILE_NAME);
  95. StringBuilder sb=new StringBuilder("");
  96. byte[] buff=new byte[1024];
  97. int hasRead=0;
  98. while ((hasRead=fis.read(buff))!=-1){
  99. sb.append(new String(buff,0,hasRead));
  100. }
  101. return sb.toString();
  102. } catch (IOException e) {
  103. e.printStackTrace();
  104. }
  105. }
  106. return null;
  107. }
  108.  
  109. private void write(String content){
  110. if (isExternalStorageWritable()){
  111. // File sdCard=Environment.getExternalStorageDirectory();
  112. File sdCard=getAlbumStorageDir(MainActivity.this,"test");
  113. try {
  114. File targetFile=new File(sdCard.getCanonicalPath()+FILE_NAME);
  115. RandomAccessFile raf=new RandomAccessFile(targetFile,"rw");
  116. raf.seek(targetFile.length());
  117. raf.write(content.getBytes());
  118. raf.close();
  119. } catch (IOException e) {
  120. e.printStackTrace();
  121. }
  122. }
  123. }
  124. }
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  2. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  3.  
  4. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  5. xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
  6. android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
  7. android:paddingRight="@dimen/activity_horizontal_margin"
  8. android:paddingTop="@dimen/activity_vertical_margin"
  9. android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
  10.  
  11. <EditText
  12. android:id="@+id/edit_area"
  13. android:lines="5"
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content" />
  16. <Button
  17. android:id="@+id/read"
  18. android:layout_below="@id/edit_area"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:text="读入"/>
  22. <Button
  23. android:id="@+id/write"
  24. android:layout_toRightOf="@id/read"
  25. android:layout_below="@id/edit_area"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:text="写入"/>
  29. <Button
  30. android:id="@+id/delete"
  31. android:layout_below="@id/edit_area"
  32. android:text="删除"
  33. android:layout_toRightOf="@id/write"
  34. android:layout_width="wrap_content"
  35. android:layout_height="wrap_content" />
  36. </RelativeLayout>

参考自:

  http://developer.android.com/training/basics/data-storage/files.html

Android 文件读写的更多相关文章

  1. [转]Android - 文件读写操作 总结

     转自:http://blog.csdn.net/ztp800201/article/details/7322110 Android - 文件读写操作 总结 分类: Android2012-03-05 ...

  2. android 文件读写工具类

    将可以序列化的对象通过base64编码后进行保存 但是感觉多数情况下,不需要采用这个功能,直接保存原始的json字符串,取出来之后再进行解析即可 package com.wotlab.home.mon ...

  3. Android - 文件读写操作 总结

    在android中的文件放在不同位置,它们的读取方式也有一些不同. 本文对android中对资源文件的读取.数据区文件的读取.SD卡文件的读取及RandomAccessFile的方式和方法进行了整理. ...

  4. android 文件读写权限的设定

    读取本地文件的权限问题 2016年08月15日 21:41:30 阅读数:2520 在一个音乐app过程中需要读取手机本地内存卡中的音乐文件并可以播放,具体遇到的问题如下:工程没有错误,运行出现以下信 ...

  5. Android 文件读写高级

    往设备里写文件有几种选择,写在内存中,或SD卡中. 往内存里写好处是,可以写在 data/data/包名 文件夹里,而此文件是不可访问的(除非 root).这样可以增加文件的安全性,避免被误删.缺点也 ...

  6. Android 文件读写的例子

    import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStrea ...

  7. 2017-6-14 踩坑小结(Android文件读写 相关问题)

    填坑 getSlotFromBufferLocked: unknown buffer: 0xab7115e0 1. 在棉花糖(6.0)上莫名出现 未知缓冲 错误,百度了一下,貌似这个是Android6 ...

  8. Android 数据存储02之文件读写

    Android文件读写 版本 修改内容 日期 修改人 V1.0 原始版本 2013/2/25 skywang Android文件读写的有两种方式.一种,是通过标准的JavaIO库去读写.另一种,是通过 ...

  9. Cocos2d-x在win32,android和IOS下的文件读写问题

    最近在学习和使用Cocos2d-x框架,虽然说的是跨平台,但是在用VS进行开发,然后移植到android或IOS下,也可能会出现各种问题,需要做细微的调整. 例如我在做文件读写操作的时候,很可能在wi ...

随机推荐

  1. ASP.NET下回车键的触发效果

    在ASP.NET下,在客户端触发回车键,默认调用了页面中第一个button,这有时是非常头痛的,比如页面的第一个按键是注销键时,想想也够可怕了. .net提供设置默认回车键的属性,this.Form. ...

  2. mac osx Forbidden You don't have permission to access / on this server解决方法

    (1)首先查看*.conf 是否有读写权限,如果没有要将文件赋予读写权限,比如 localhost.conf (2)再查看/Users/username/Sites/localhost/文件夹是否有i ...

  3. 弱省互测#2 t2

    题意 给两个树,大小分别为n和m,现在两棵树各选一些点(包括1),使得这棵树以1号点为根同构(同构就是每个点的孩子数目相同),求最大的同构树.(n, m<=500) 分析 我们从两棵树中各取出一 ...

  4. JavaScript-Object基础知识

    1.   定义:对象是JS的核心概念,也是最重要的数据类型.js的所有数据都可以被视为对象.                 对象是一种无序的数据集合,由若干个键值对(key:value)构成,由{ ...

  5. Php:学习笔记(一):版本选择

    (注:本文来自网络) 超过75%的网站使用了PHP作为开发语言,wordpress,phpmyadmin和其他一些开源项目的盛行,带来了一大批的长尾用户.然而,他们一般安装之后却很少升级.下图是目前P ...

  6. WIN32 窗口封装类实现

    CQWnd.h窗口类定义 // QWnd.h: interface for the CQWnd class. // ////////////////////////////////////////// ...

  7. JVM中对象的销毁

    1.可达性分析算法: 可达性分析算法用来寻找将要销毁的对象,它的基本思路是:通过一系列的称为“GC ROOTs”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC ...

  8. Vuforia点击屏幕自动对焦,过滤UGUI的按钮

    //点击屏幕自对对焦 #if UNITY_EDITOR )) #elif UNITY_ANDROID || UNITY_IPHONE && Input.GetTouch().phase ...

  9. 实用redis前需了解的5大事项

    百万个键,每个值的长度是32-character,那么在使用6-character长度键名时,将会消耗大约96MB的空间,但是如果使用12-character长度的键名时,空间消耗则会提升至111MB ...

  10. web端限时活动逻辑处理总结

    由于要在web端做一个限时活动的功能,功能大致为:一个小时内可以报名参加活动,然后给予报名者奖品,先到先得.用到一些处理逻辑做下总结,以前没有做过类似的东西,都是自己先体验其他网站的报名方式,然后再摸 ...