一、简述
apk中有两种资源文件,raw下的和assert下的,这些数据只能读取,不能写入,两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类,res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹
SD卡中的文件使用FileInputStream和FileOutputStream进行文件的操作。
存放在数据区(/data/data/..)的文件只能使用openFileOutput和openFileInput进行操作。注意这里不能使用FileInputStream和FileOutputStream进行文件的操作。
二、实例代码
getFilesDir();
getExternalCacheDir();
getPackageCodePath();
getPackageResourcePath();
getCacheDir();
getExternalFilesDir(null);
Environment.getExternalStorageState();
Environment.getExternalStorageDirectory();
Environment.getDataDirectory();
Environment.getDownloadCacheDirectory();
Environment.getRootDirectory();
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
以上几个测试对应的路径为:
Environment.getDataDirectory() =
/data
Environment.getDownloadCacheDirectory() =
/data/cache (vivo)
/cache (meizu)
Environment.getExternalStorageDirectory() =
/storage/emulated/0
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) =
/storage/emulated/0/Pictures
Environment.getRootDirectory() =
/system
getPackageCodePath() =
/data/app/com.demo.mydemoapplication-1/base.apk
getPackageResourcePath() =
/data/app/com.demo.mydemoapplication-1/base.apk
getCacheDir() =
/data/data/com.demo.mydemoapplication/cache (meizu)
/data/user/0/com.demo.mydemoapplication/cache (vivo)
getDatabasePath(“test”) =
/data/data/com.demo.mydemoapplication/databases/test
getDir(“test”, Context.MODE_PRIVATE) =
/data/data/com.demo.mydemoapplication/app_test
getExternalCacheDir() =
/storage/emulated/0/Android/data/com.demo.mydemoapplication/cache
getExternalFilesDir(“test”) =
/storage/emulated/0/Android/data/com.demo.mydemoapplication/files/test
getExternalFilesDir(null) =
/storage/emulated/0/Android/data/com.demo.mydemoapplication/files
getFilesDir() =
/data/data/com.demo.mydemoapplication/files (meizu)
/data/user/0/com.demo.mydemoapplication/files (vivo)
三、常用文件读写方式
Java IO中用于读写文件的四个抽象类:Reader,Writer,InputStream,OutputStream,根据流所处理的数据类型分为两类:
(1)字节流:用于处理字节数据。(InputStream,OutputStream)
(2)字符流:用于处理字符数据,Unicode字符数据。(Reader,Writer)
IO流的结构划分如下,图片来自网络
以上图片来自网络
ps:sd卡的文件读写需要添加对应权限
<!--文件读写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--文件夹的创建和删除权限(目前使用会提示仅系统APP才会授予该权限)-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
资源文件(只读)两种资源文件,使用两种不同的方式进行打开使用。
raw文件夹下资源获取:InputStream in = getResources().openRawResource(R.raw.test);
asset文件夹下资源获取:InputStream in = getResources().getAssets().open(fileName);
注:在使用InputStream的时候需要在函数名称后加上throws IOException。
数据区文件(/data/data/<应用程序名>目录上的文件)
(1)写操作:
FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE);
(2)读操作:FileInputStream fin = openFileInput(fileName);
(3)写操作中的使用模式:
MODE_APPEND:即向文件尾写入数据
MODE_PRIVATE:即仅打开文件可写入数据
MODE_WORLD_READABLE:所有程序均可读该文件数据
MODE_WORLD_WRITABLE:即所有程序均可写入数据。
sd卡文件操作
(1)读操作
FileInputStream fin = new FileInputStream(fileName);
(2)写操作
FileOutputStream fout = new FileOutputStream(fileName);
(3)检查sd卡内存状态
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
sd卡已安装,可用
开始读写, 一般写在\data\data\com.test\files\里面,打开DDMS查看file explorer是可以看到仿真器文件存放目录的结构的
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录
File saveFile = new File(sdCardDir, “test1.txt”);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write(“woshixinjiade”.getBytes());
outStream.close();
}
从resource的raw中读取文件数据
String res = "";
try{
//得到资源中的Raw数据流
InputStream in = getResources().openRawResource(R.raw.test);
//得到数据的大小
int length = in.available();
byte [] buffer = new byte[length];
//读取数据
in.read(buffer);
//依test.txt的编码类型选择合适的编码,如果不调整可能会乱码
res = new String(buffer, "UTF-8");
//关闭
in.close();
} catch (Exception e){
e.printStackTrace();
}
从resource的assert中读取文件数据
String fileName = "test.txt"; //文件名字
String res="";
try{
//得到资源中的asset数据流
InputStream in = getResources().getAssets().open(fileName);
int length = in.available();
byte [] buffer = new byte[length];
in.read(buffer);
in.close();
res = new String(buffer, "UTF-8");
} catch (Exception e){
e.printStackTrace();
}
读写/data/data/<应用程序名完整包名>/files目录下的文件
//FileOutputStream 写数据,写文件在./data/data/com.tt/files/下面
public void writeFile(String fileName,String str) throws IOException{
try{
FileOutputStream fout =openFileOutput(fileName, Context.MODE_PRIVATE);
byte [] bytes = str.getBytes();
fout.write(bytes);
fout.close();
} catch (Exception e){
e.printStackTrace();
}
}
//FileInputStream 读数据,读文件在./data/data/com.tt/files/下面
public String readFile(String fileName) throws IOException{
String res="";
try{
FileInputStream fin = openFileInput(fileName);
int length = fin.available();
byte [] buffer = new byte[length];
fin.read(buffer);
res = new String(buffer, "UTF-8");
fin.close();
} catch (Exception e){
e.printStackTrace();
}
return res;
}
//FileOutputStream 写数据到SD中的文件
public void writeToSdCardFile(String fileName,String str) throws IOException{
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录
File saveFile = new File(sdCardDir, fileName);
if(saveFile.exists()){
try{
FileOutputStream fos = new FileOutputStream(saveFile);
byte [] bytes = str.getBytes();
fos.write(bytes);
fos.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
//FileInputStream 读SD中的文件
public String readSdCardFile(String fileName) throws IOException{
File file = new File(fileName);
if(file.exists()){
String res="";
try{
FileInputStream fis = new FileInputStream(file);
int length = fis.available();
byte [] buffer = new byte[length];
fis.read(buffer);
res = new String(buffer, "UTF-8");
fis.close();
} catch (Exception e){
e.printStackTrace();
}
return res;
}
}
使用File类进行文件的读写
//FileInputStream读文件
public String readSDFile(String fileName) throws IOException {
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
int length = fis.available();
byte [] buffer = new byte[length];
fis.read(buffer);
res = new String(buffer, "UTF-8");
fis.close();
return res;
}
//FileOutputStream写文件
public void writeSDFile(String fileName, String str) throws IOException{
File file = new File(fileName);
FileOutputStream fos = new FileOutputStream(file);
byte [] bytes = str.getBytes();
fos.write(bytes);
fos.close();
}
使用BufferedReader进行读写
//********************FileWriter****************************************
FileReader r = new FileReader(file);
BufferedReader br = new BufferedReader(r);
//由于每次只能读一行,就让其不断地读
StringBuffer msg = new StringBuffer();
String s;
while ((s = br.readLine()) != null) {
msg = msg.append(s+“\n”); //必须要加\n 否则全部数据变成一行
}
//释放资源
r.close;
br.close;
//********************InputStreamReader**********************************
InputStreamReader isr = new InputStreamReader(is, "UTF-8");//指定编码格式
BufferedReader bfr = new BufferedReader(isr);
String in = "";
while ((in = bfr.readLine()) != null) {
Log.i(TAG, in);
}
//释放资源
bfr.close();
isr.close();
文件拷贝
/**
* 拷贝一个文件,srcFile源文件,destFile目标文件
*
* @param path
* @throws IOException
*/
public boolean copyFileTo(File srcFile, File destFile) throws IOException {
if (srcFile.isDirectory() || destFile.isDirectory())
return false;// 判断是否是文件
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
int readLen = 0;
byte[] buf = new byte[1024];
while ((readLen = fis.read(buf)) != -1) {
fos.write(buf, 0, readLen);
}
fos.flush();
fos.close();
fis.close();
return true;
}
其他常用操作
String Name = File.getName(); //获得文件或文件夹的名称:
String parentPath = File.getParent(); //获得文件或文件夹的父目录
String path = File.getAbsoultePath();//绝对路经
String path = File.getPath();//相对路经
File.createNewFile();//建立文件
File.mkDir(); //建立文件夹
File.mkDirs(); //建立多级文件夹
File.isDirectory(); //判断是文件或文件夹
File[] files = File.listFiles(); //列出文件夹下的所有文件和文件夹
String[] files = File.lists(); //列出文件夹下的所有文件和文件夹名
File.renameTo(dest); //修改文件夹和文件名
File.delete(); //删除文件夹或文件
FileInputStream fin = new FileInputStream(fileName);
InputStream in = new BufferedInputStream(fin);
以字节的方式读写文件,速度较快
//以追加的方式写文件
public static void writeFileAppend(String path, byte[] b) {
FileOutputStream fs = null;
BufferedOutputStream bos = null;
try {
fs = new FileOutputStream(new File(path), true);//这里改成false则为覆盖的方式写文件
bos = new BufferedOutputStream(fs);
bos.write(b);
bos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fs != null)
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//读文件
public static byte[] readFile(String path) {
int len= (int) new File(path).length();
byte b[] = new byte[len];
StringBuffer result=new StringBuffer();
BufferedInputStream bis = null;
FileInputStream fi = null;
try {
fi = new FileInputStream(new File(path));
bis = new BufferedInputStream(fi);
int temp;
int i=0;
while ((b[i] = (byte)bis.read()) != -1) {
i++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fi != null) {
try {
fi.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return b;
}