安卓学习笔记(8)-外部存储的读写操作

本文详细介绍了在安卓4.4及以后版本中应用程序如何处理外部存储的问题,特别是针对机身存储和SD卡的访问限制。文章提供了具体的代码示例,展示了如何在这些设备上进行文件的读写操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

记在前面

安卓4.4之后,如果如果同时使用了机身存储和SD卡, 那么应用程序将无法在SD卡中创建、修改、删除数据。但是应用程序仍然可以往主存储(机身存储)的任意目录中写入数据,不受任何限制。

也就是说,在安卓4.4之后,如果要写入外部存储,其实是写入了手机自带的存储空间中,而不能写入你自己插入的外置SDcard中。

写入SDcard

File dir = new File(Environment.getExternalStorageDirectory() + "/" + dirName);
File dataFile = new File(dir, fileName);

其中,通过语句Environment.getExternalStorageDirectory() 可以获取SDcard(手机自带存储空间)的根目录。根目录也可以使用下面的路径来表示;

/storage/emulated/0

/storage/sdcard0(sdcard1表示外置的SD卡,但是你在使用的时候会报权限不足)

接下来需要进行判断,没有文件夹要创建文件夹,没有文件就需要创建文件,这里使用如下的方法就可以实现

if (!dir.exists()) {
  dir.mkdir();
}
if (!dataFile.exists()) // 判断文件是否存在
{
  dataFile.createNewFile();// 文件不存在,创建文件
}

写入数据

FileOutputStream fos = new FileOutputStream(dataFile, true);
fos.write(string.getBytes("utf-8"));
fos.flush();//强制写出缓冲区的数据
fos.close();

具体的方法

public void saveCurrentText(String string) {
        File dir = new File(Environment.getExternalStorageDirectory() + "/"
                + dirName);
        File dataFile = new File(dir, fileName);
        try {
            if (!dir.exists()) {
                dir.mkdir();
            }
            if (!dataFile.exists()) // 判断文件是否存在
            {
                dataFile.createNewFile();// 文件不存在,创建文件
            }
            FileOutputStream fos = new FileOutputStream(dataFile, true);
            fos.write(string.getBytes("utf-8"));
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {// 没有挂载SD卡时抛出
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

从SD卡读出数据

与写入SD卡一样,需要检测文件夹和文件是否存在,读出方法如下

public String readSavedText(String dirName,String fileName) {
        // File dir = new File(Environment.getExternalStorageDirectory() +
        // dirName);
        File dir = new File(Environment.getExternalStorageDirectory() + "/"
                + dirName);
        File dataFile = new File(dir, fileName);
        try {
            FileInputStream fis = new FileInputStream(dataFile);
            byte[] bytes = new byte[fis.available()];
            fis.read(bytes);
            fis.close();
            String str = new String(bytes, "utf-8");
            return str;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "NO_SUCH_FILE";
    }

其中available()方法是可以在读操作前先得知数据流里有多少个字节可以读取,但是这个方法只能读取小文件,过大的文件可能会迅速占满你的运行内存;同时这个方法读取网络资源的时候也是有问题的,因为socket发送数据有时可能是分好几批到的,你需要循环读取好几次才能获取到完整的数据。

写在后面

为了方便之后的使用,我将外部存储的读写封装了一下,供大家交流使用【FileRW.java】

package com.example.internalstoage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.os.Environment;

public class FileRW {

    private String dirName;
    private String fileName;

    public FileRW(String dirName, String fileName) {
        this.dirName = dirName;
        this.fileName = fileName;
    }

    public FileRW(String dirName) {
        this.dirName = dirName;
    }

    public void saveCurrentText(String string) {
        File dir = new File(Environment.getExternalStorageDirectory() + "/"
                + dirName);
        File dataFile = new File(dir, fileName);
        try {
            if (!dir.exists()) {
                dir.mkdir();
            }
            if (!dataFile.exists()) // 判断文件是否存在
            {
                dataFile.createNewFile();// 文件不存在,创建文件
            }
            FileOutputStream fos = new FileOutputStream(dataFile, true);
            fos.write(string.getBytes("utf-8"));
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {// 没有挂载SD卡时抛出
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public String readSavedText() {
        // File dir = new File(Environment.getExternalStorageDirectory() +
        // dirName);
        File dir = new File(Environment.getExternalStorageDirectory() + "/"
                + dirName);
        File dataFile = new File(dir, fileName);
        try {
            FileInputStream fis = new FileInputStream(dataFile);
            byte[] bytes = new byte[fis.available()];
            fis.read(bytes);
            fis.close();
            String str = new String(bytes, "utf-8");
            return str;
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return "NO_SUCH_FILE";
    }

    public File[] getFilefromDir() {
        File dir = new File(Environment.getExternalStorageDirectory() + "/"
                + dirName);
        File[] children = dir.listFiles();
        return children;
    }

    public void setDirName(String dirName) {
        this.dirName = dirName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getDirName() {
        return dirName;
    }

    public String getFileName() {
        return fileName;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值