记在前面
安卓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;
}
}