最近在学习安卓,总结记录下app读写文件的位置和方法;
安卓的app可以读写的位置为:
1、内置data目录下对应app名称的目录;
2、扩展SD卡(包括虚拟的内置SD卡和外置SD卡);
那么先讲讲内置data目录下文件的读写,这个位置的读写有提供一套单独的API来读写,如下:
//写数据 private void writeDataFile(String fileName,String writestr) throws IOException{ try{ FileOutputStream fout =openFileOutput(fileName, Context.MODE_PRIVATE | Context.MODE_APPEND); byte[] bytes = writestr.getBytes(); // String str = new String(bytes); // Log.i(TAG, "writeDataFile:" + "bytes.toString=" + str + ";"); fout.write(bytes); fout.close(); } catch(Exception e){ e.printStackTrace(); Log.e(TAG,"writeDataFile Error!"); } } //读数据 public String readDataFile(String fileName) throws IOException{ String res = ""; try{ // String[] strings = fileList(); // for(int i = 0; i < strings.length; i++){ // Log.i(TAG, "fileList String["+i+"]="+strings[i].toString()); // } FileInputStream fin = openFileInput(fileName); int length = fin.available(); byte [] buffer = new byte[length]; fin.read(buffer); res = new String(buffer); fin.close(); } catch(Exception e){ e.printStackTrace(); Log.e(TAG, "readDataFile Error!"); } return res; } //删除文件 deleteFile(getResources().getString(R.string.testfilename));
当然,实验发现也可以通过
Environment.getDataDirectory().getPath()获取对应的data路径后通过普通的方法读写data中的文件;
接下来说明如何读取SD卡内的文件:
1、获取SD卡读写权限:
在manifests中增加以下权限,获取读写SD卡的权限;
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
2、获取SD卡的路径:
系统提供了以下接口来获取SD卡路径
Environment.getExternalStorageDirectory().getPath();
但是现阶段系统通常都通过虚拟的方式模拟一个内置SD卡,用户可能同时插入一个外置SD卡;双sd卡时,以上接口会根据”设置“里面的数据存储位置选择,获得的是内置sd卡或外置sd卡;
系统并没有区分内置SD卡或者外置SD卡,目前获取外置SD卡的方法如下,但是可能在不同机器上回存在一定的问题:
/** * 获取sd卡路径 * 双sd卡时,获得的是外置sd卡 * @return */ private String getSDCardPath() { String sdcard_path = null; String sd_default = Environment.getExternalStorageDirectory() .getAbsolutePath(); Log.d("text", sd_default); if (sd_default.endsWith("/")) { sd_default = sd_default.substring(0, sd_default.length() - 1); } InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; // 得到路径 try { Runtime runtime = Runtime.getRuntime(); Process proc = runtime.exec("mount"); is = proc.getInputStream(); isr = new InputStreamReader(is); String line; br = new BufferedReader(isr); while ((line = br.readLine()) != null) { if (line.contains("secure")) continue; if (line.contains("asec")) continue; if (line.contains("fat") && line.contains("/mnt/")) { String columns[] = line.split(" "); if (columns != null && columns.length > 1) { if (sd_default.trim().equals(columns[1].trim())) { continue; } sdcard_path = columns[1]; return sdcard_path; } } else if (line.contains("fuse") && line.contains("/mnt/")) { String columns[] = line.split(" "); if (columns != null && columns.length > 1) { if (sd_default.trim().equals(columns[1].trim())) { continue; } sdcard_path = columns[1]; return sdcard_path; } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ try { if( br !=null){ br.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(isr!=null){ isr.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(is!=null){ is.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return Environment.getExternalStorageDirectory().getPath(); }
另外,也有一切其他方法来读写文件:
一、使用RandomAccessFile进行文件的读写:RandomAccessFile的使用方法比较灵活,功能也比较多,可以使用类似seek的方式可以跳转到文件的任意位置,从文件指示器当前位置开始读写。 它有两种构造方法 new RandomAccessFile(f,"rw");//读写方式 new RandomAccessFile(f,"r");//只读方式
使用实例:
- /*
- * 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。
- */
- import java.io.*;
- public class RandomAccessFileDemo {
- public static void main(String[] args) throws Exception {
- RandomAccessFile file = new RandomAccessFile("file", "rw");
- // 以下向file文件中写数据
- file.writeInt(20);// 占4个字节
- file.writeDouble(8.236598);// 占8个字节
- file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取
- file.writeBoolean(true);// 占1个字节
- file.writeShort(395);// 占2个字节
- file.writeLong(2325451l);// 占8个字节
- file.writeUTF("又是一个UTF字符串");
- file.writeFloat(35.5f);// 占4个字节
- file.writeChar('a');// 占2个字节
- file.seek(0);// 把文件指针位置设置到文件起始处
- // 以下从file文件中读数据,要注意文件指针的位置
- System.out.println("——————从file文件指定位置读数据——————");
- System.out.println(file.readInt());
- System.out.println(file.readDouble());
- System.out.println(file.readUTF());
- file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。
- System.out.println(file.readLong());
- file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。
- System.out.println(file.readFloat());
- //以下演示文件复制操作
- System.out.println("——————文件复制(从file到fileCopy)——————");
- file.seek(0);
- RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");
- int len=(int)file.length();//取得文件长度(字节数)
- byte[] b=new byte[len];
- file.readFully(b);
- fileCopy.write(b);
- System.out.println("复制完成!");
- }
- }
二、读取资源文件:
1) 从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);
- //关闭
- in.close();
- }catch(Exception e){
- e.printStackTrace();
- }
2) 从resource的asset中读取文件数据总结:
- 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);
- }catch(Exception e){
- e.printStackTrace();
- }
1、apk中有两种资源文件,使用两种不同的方式进行打开使用。 raw使用InputStream in = getResources().openRawResource(R.raw.test); asset使用InputStream in = getResources().getAssets().open(fileName);
这些数据只能读取,不能写入。更重要的是该目录下的文件大小不能超过1M。
同时,需要注意的是,在使用InputStream的时候需要在函数名称后加上throws IOException。
2、SD卡中的文件使用FileInputStream和FileOutputStream进行文件的操作。 3、存放在数据区(/data/data/..)的文件只能使用openFileOutput和openFileInput进行操作。 注意不能使用FileInputStream和FileOutputStream进行文件的操作。 4、RandomAccessFile类仅限于文件的操作,不能访问其他IO设备。它可以跳转到文件的任意位置,从当前位置开始读写。
5、InputStream和FileInputStream都可以使用skip和read(buffre,offset,length)函数来实现文件的随机读取。