Android基础篇 文件读写

一、文件读写权限

(1)权限

读写 外部存储 中的文件时,需要 读写权限;

读写 “ 内部存储 ” 中的文件,“ 不需要 ” 读写权限

  • 向外部存储 写入 文件 【write】
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 从外部存储 读取 文件 【read】
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

(2)提醒

从 API 等级 19 开始,读取函数 getExternalFilesDirgetExternalCacheDir 得到的外部存储路径中的文件时,不再需要读写权限

二、内部存储和外部存储的区别

File 对象适合按照从开始到结束的顺序不跳过地读取或写入大量数据。

例如,它适合于图片文件或通过网络交换的任何内容

(1)内部存储的特点

  • 始终可用
  • 只有本应用可以访问到此保存的文件
  • 用户卸载应用时,系统会从内部存储中移除应用的所有文件

适用场景:确保用户或其他应用均无法访问您的文件时,内部存储是最佳选择

(2)外部存储的特点

  • 并非始终可用,因为用户可采用 USB 存储设备的形式装载外部存储,并在某些情况下会从设备中将其移除(不过目前大部分的智能手机都不再支持可拆卸式的 SD 卡形式了)
  • 全局可读的,因此此处保存的文件可能不受您控制地被读取
  • 当用户卸载您的应用时,只有在您通过 getExternalFilesDir() 将您的应用的文件保存在目录中时,系统才会从此处移除您的应用的文件

适用场景:对于无需访问限制以及您希望与其他应用共享或允许用户使用计算机访问的文件,外部存储是最佳位置

(3)提示

提示:尽管应用默认安装在内部存储中,但您可在您的清单文件中指定 android:installLocation 属性,这样您的应用便可安装在在外部存储中。

当 APK 非常大且它们的外部存储空间大于内部存储时,用户更青睐这个选择。

当文件不想让其它应用访问时,可以选择内部存储;

当文件想要长期保存时,可以选择外部存储(不过外部存储中也有私有位置,即存储在该路径下的文件会随 apk 的卸载而自动移除)

三、访问外部存储的相应函数

(1)事前工作:测试是否允许文件读写【针对外部存储】

在进行文件操作之前最好先测试一下外部存储的状态,使用函数getExternalStorageState,当返回结果为 MEDIA_MOUNTED,表示可以继续下面的文件读写

/* Checks if external storage is available for read and write */
/* 检查外部存储器是否可用于读和写 */
public boolean isExternalStorageWritable(){
	String state = Environment.getExternalStorageState();
	if(Environment.MEDIA_MOUNTED.equals(state)){
		return true;
	}
	 Log.e(TAG, "isExternalStorageWritable: " + state);
     return false;
}

正如上面所言,外部存储也分为两大块,一块是完全的公共区域,在里面的文件需要显式的移除;另一块就是相对私有的区域,虽然在该路径下也可以被其他应用访问,不过该路径下的文件会随应用的卸载而自动移除

(2)访问公共区域

- 直接返回外部存储主目录

Environment.getExternalStorageDirectory

代码:

String mainDir = Environment.getExternalStorageDirectory().getAbsolutePath();

结果:

/storage/emulated/0

- 访问专用目录

Android 在外部存储中将一些相同文件类型的文件放置在了同一个目录下,比如图片,视频,文档,音乐等。

如果想要得到专用目录,可以使用函数Environment.getExternalStoragePublicDirectory

标准的存储目录如下

public static final String[] STANDARD_DIRECTORIES = {
    DIRECTORY_MUSIC, //目录_音乐
    DIRECTORY_PODCASTS,//目录_播客 博客 精采广播
    DIRECTORY_RINGTONES,//目录_来电铃声 手机铃声 随机铃声
    DIRECTORY_ALARMS,//目录_警告 闹钟铃声 闹钟
    DIRECTORY_NOTIFICATIONS,//目录_通知
    DIRECTORY_PICTURES,//目录_相关图片
    DIRECTORY_MOVIES,//目录_电影
    DIRECTORY_DOWNLOADS,//目录_下载
    DIRECTORY_DCIM,//目录_数据中心基础设施管理
    DIRECTORY_DOCUMENTS//目录_单据 证件 文件
};

代码:

String dcimDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
.getAbsolutePath();

String pictureDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoultPath();

结果:

/storage/emulated/0/Pictures  
/storage/emulated/0/DCIM

- 访问私有区域

使用函数getExternalFilesDir(String)

  1. 参数为空表示返回外部存储上应用的专用目录的 “ 根 ” 目录
String fileDir = getExternalFilesDir(null).getAbsolutePath();

结果:

/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files
  1. 创建标准目录
String movieDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES).getAbsolutePath();
String documentDir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();

结果:

/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files/Movies
/storage/emulated/0/Android/data/com.penglaoxi.filedemo/Documents

四、向外部存储读写文件

使用 java.io 类即可

(1)向外部存储【写入】字符串、图片

- 写入字符串
private void writeStringToFile(String str){
	//判断外部存储是否允许写入操作
	if(!isExternalStorageWritable()){
	//如果不允许,退出方法
	return;
    }

	//如果允许写入操作,执行以下操作
	File dir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
	//日志输出路径
	Log.e("TAG","writeStringToFile: dir = " + dir.getAbsolutePath());
	
	//如果目标不存在
	if(!dir.exists()){
	//创建多级目录
	dir.mkdirs();
    }
	
	//创建一个txt的文件保存字符串,"str"为自定义的文件名称
	File file = new File(dir,"str.txt");
	
	//如果文件存在
	if(file.exists()){
	//如果存在命名相同的文件,就删除
	file.delete();
	}
	
	FileOutputStream fos = null;
	BufferedOutputStream bos = null;
	try{
	//创建文件
	file.createNewFile();
	//文件输出流(file)
	fos = new FileOutputStream(file);
	//缓冲输出流(fos)
	bos = new BufferedOutputStream(fos);
	
	bos.write(str.getBytes());
	
	//关闭缓存流
	bos.close();
	//关闭输入流
	fos.close();
	} catch (IOException e) {
    e.printStackTrace();
   }finally{
	 try{
		if(bos != null){
        bos.close();
	  }
	  	if(fos != null){
        fos.close();
      }
	}catch (IOException e) {
       e.printStackTrace();
     }
  }
}

/* Checks if external storage is available for read and write */
    public boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            return true;
        }
        Log.e(TAG, "isExternalStorageWritable: " + state);
        return false;
    }
- 写入图片
private void writeImageToFile(Bitmap bitmap) {
	//判断外部存储是否允许写入操作
    if (!isExternalStorageWritable()) {
     return;
    }
	
	//获取外部文件目录
	File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
	//输出相片路径【外部文件目录】
	Log.e(TAG, "writeImageToFile: dir = " + dir.getAbsolutePath());

	if(!dir.exists()){
	//创建多级目录
	dir.mkdirs();
	}
	
	File file = new File(dir,"penglaoxi.png")
	//如果文件存在一致
	if(file.existe()){
	//删除目标文件
	file.delete();
	}

	FileOutputStream fos = null;
	BufferedOutputStream bos = null;
	
	try{
		//创建文件
		file.createNewFile();
		
		fos = new FileOutputStream(file);
		bos = new BufferedOutputStream(fos);
		//压缩图片
		bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
		//刷新
		bos.flush();

        bos.close();
        fos.close();
	} catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null) {
                 bos.close();
               }
             if (fos != null) {
             fos.close();
            }
          } catch (IOException e) {
         e.printStackTrace();
     }
  }
}

writeStringToFile(String) 函数用于将字符串写入本地,选择本地路径为外部存储私有路径中的文档专用目录

/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files/Documents

writeImageToFile(Bitmap) 函数用于将图片写入本地,选择本地路径为外部存储私有路径中的图片专用目录

/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files/Pictures

进行写入操作前,先判断外部存储是否可用;然后判断文件目录是否存在,不存在则新建;最后写入文件

(2)向外部存储【读取】文本文件,图片文件

读取外部存储中的文本文件 - readStringFromFile
private String readStringFromFile() {
	 //判断是否允许读取操作
	 if (!isExternalStorageWritable()) {
            return null;
      }

	 //获取外部存储目录     
     File dir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
     Log.e(TAG,"readStringFromFile: dir = " + dir.getAbsolutePath());

	if(!dir.exists()){
	 return null;
	}
	
	File file = new File(dir,"str.txt");
	if(!file.exists()){
	return null;
	}
	
	//文件输入流
	FileInputStream fis = null;
	//字符流 转换流 输入流
	InputStreamReader isr = null;
	//缓冲区读取 缓冲流 输入流
	BufferedReader br = null;
	
	//字符串缓冲
	StringBuffer sb =  new StringBuffer();
	try{
		fis = new FileInputStream(file);
		isr = new InputStreamReader(fis);
		br = new BufferedReader(isr);
		
		String line;
		
		//字符串缓冲 写入缓冲流 br (逐行读取) 
		sb.append(br.readLine());
		
		//如果文件的字符串不为空
		while((line = br.readLine()) != null){
		//循环写入每一行的数据
		sb.append("\n" + line);
		}
		
		br.close();
        isr.close();
        fis.close();
	} catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
     //返回读取的文字   
     return sb.toString();
}
读取外部存储中的图片文件 - readBitmapFromFile
private Bitmap readBitmapFromFile() {
    if (!isExternalStorageWritable()) {
        return null;
    }

	File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
	Log.e(TAG, "readBitmapFromFile: dir = " + dir.getAbsolutePath());

	if(!dir.existe()){
	 return null;
	}

	File file = new File(dir,"penglaoxi.png");
	
	if(!file.exists()){
	 return null;
	}
	
	FileInputStream fis = null;
	BufferedInputStream bis = null;
	
 	Bitmap bitmap = null;
	try{
		fis = new FileInputStream(file);
		bis = new BufferedInputStream(fis);
		//位图压缩
		bitmap = BitmapFactory.decodeStream(bis);
		bis.close();
		fis.close();
	}catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bis != null) {
                bis.close();
            }
            if (fis != null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	 return bitmap;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android Studio中,有多种方式可以进行文件操作。其中包括应用程序下的文件、assets下的文件取、raw下的文件取以及SD卡下的文件。 首先,对于应用程序下的文件Android文件存储在应用的内部存储空间中,在这个空间中,你可以使用openFileOutput()方法创建一个输出流来文件。例如,可以使用以下代码创建一个文件入内容: ```java public void WriteSysFile(Context context, String filename) { try { FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); osw.write("随便插入点啥"); osw.flush(); fos.flush(); osw.close(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } ``` 这个方法将在应用的内部存储空间中创建一个名为"appfile.txt"的文件,并将"随便插入点啥"入到该文件中。 其次,如果需要取assets文件夹下的文件,可以使用context.getResources().getAssets().open()方法来获取一个InputStream对象,然后再使用这个对象进行文件取操作。 另外,如果想要取res/raw文件夹下的文件,可以使用context.getResources().openRawResource()方法来获取一个InputStream对象,并通过该对象进行文件取。 最后,如果要进行SD卡下的文件操作,可以使用File类来指定文件的路径,并使用FileOutputStream和FileInputStream来进行文件操作。 需要注意的是,在进行SD卡下的文件操作时,需要确保已经获取了相应的权限。 总结起来,Android Studio提供了多种方式用于文件操作,包括应用程序下的文件、assets下的文件取、raw下的文件取以及SD卡下的文件。具体选择哪种方式取决于你的需求和文件的位置。 引用自:本篇介绍android开发中4中文件方式。 引用自:在as里提供了DeviceFileExplorer查看应用程序的目录,具体路径是/data/data/应用程序包名。 引用自:首先添加raw文件夹,在res文件夹上右键添加。这里的文件最后会被打包到apk中,同时会被编译到R.java文件中,访问的时候直接使用资源ID。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

其子昱舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值