安卓app的文件读写方法

最近在学习安卓,总结记录下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));

以上接口直接对应/data/data/[packname]/file/目录建立和读写文件;不需要另外写对应的文件路径;

当然,实验发现也可以通过

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");//只读方式

使用实例:

[java]  view plain  copy
  1. /*  
  2.  * 程序功能:演示了RandomAccessFile类的操作,同时实现了一个文件复制操作。  
  3.  */    
  4.     
  5. import java.io.*;    
  6.     
  7. public class RandomAccessFileDemo {    
  8.  public static void main(String[] args) throws Exception {    
  9.   RandomAccessFile file = new RandomAccessFile("file""rw");    
  10.   // 以下向file文件中写数据    
  11.   file.writeInt(20);// 占4个字节    
  12.   file.writeDouble(8.236598);// 占8个字节    
  13.   file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取    
  14.   file.writeBoolean(true);// 占1个字节    
  15.   file.writeShort(395);// 占2个字节    
  16.   file.writeLong(2325451l);// 占8个字节    
  17.   file.writeUTF("又是一个UTF字符串");    
  18.   file.writeFloat(35.5f);// 占4个字节    
  19.   file.writeChar('a');// 占2个字节    
  20.     
  21.   file.seek(0);// 把文件指针位置设置到文件起始处    
  22.     
  23.   // 以下从file文件中读数据,要注意文件指针的位置    
  24.   System.out.println("——————从file文件指定位置读数据——————");    
  25.   System.out.println(file.readInt());    
  26.   System.out.println(file.readDouble());    
  27.   System.out.println(file.readUTF());    
  28.     
  29.   file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。    
  30.   System.out.println(file.readLong());    
  31.     
  32.   file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。    
  33.   System.out.println(file.readFloat());    
  34.       
  35.   //以下演示文件复制操作    
  36.   System.out.println("——————文件复制(从file到fileCopy)——————");    
  37.   file.seek(0);    
  38.   RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");    
  39.   int len=(int)file.length();//取得文件长度(字节数)    
  40.   byte[] b=new byte[len];    
  41.   file.readFully(b);    
  42.   fileCopy.write(b);    
  43.   System.out.println("复制完成!");    
  44.  }    
  45. }    

二、读取资源文件:

1) 从resource的raw中读取文件数据:

[java]  view plain  copy
  1. String res = "";   
  2. try{   
  3.    
  4.     //得到资源中的Raw数据流  
  5.     InputStream in = getResources().openRawResource(R.raw.test);   
  6.   
  7.     //得到数据的大小  
  8.     int length = in.available();         
  9.   
  10.     byte [] buffer = new byte[length];          
  11.   
  12.     //读取数据  
  13.     in.read(buffer);           
  14.   
  15.     //依test.txt的编码类型选择合适的编码,如果不调整会乱码   
  16.     res = new String(buffer);
  17.       
  18.     //关闭      
  19.     in.close();              
  20.   
  21.    }catch(Exception e){   
  22.       e.printStackTrace();           
  23.    }   

 2) 从resource的asset中读取文件数据

[java]  view plain  copy
  1. String fileName = "test.txt"//文件名字   
  2. String res="";   
  3. try{   
  4.   
  5.    //得到资源中的asset数据流  
  6.    InputStream in = getResources().getAssets().open(fileName);   
  7.   
  8.    int length = in.available();           
  9.    byte [] buffer = new byte[length];          
  10.   
  11.    in.read(buffer);              
  12.    in.close();  
  13.    res = new String(buffer);      
  14.   
  15.   }catch(Exception e){   
  16.   
  17.       e.printStackTrace();           
  18.   
  19.    }   

总结:

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)函数来实现文件的随机读取。

 

你可能感兴趣的:(安卓app的文件读写方法)