在android中的文件放在不同位置,它们的读取方式也有一些不同。

本文对android中对资源文件的读取、数据区文件的读取、SD卡文件的读取及RandomAccessFile的方式和方法进行了整理。供参考。

sdcard读写 默认android系统对每个app都开放读写功能。默认路径为/mnt/sdcard/ 或者/sdcard/
添加读写权限:
写外部存储即sdcard的权限:android:name="android.permission.WRITE_EXTERNAL_STORAGE"
打开关闭sdcard的权限:android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"

一、资源文件的读取:

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 = EncodingUtils.getString(buffer, "BIG5");         //关闭        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 = EncodingUtils.getString(buffer, "UTF-8");       }catch(Exception e){       e.printStackTrace();            } 


二、读写/data/data/<应用程序名>目录上的文件:

//写数据public void writeFile(String fileName,String writestr) throws IOException{   try{         FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE);         byte [] bytes = writestr.getBytes();         fout.write(bytes);         fout.close();       }         catch(Exception e){         e.printStackTrace();        } } //读数据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 = EncodingUtils.getString(buffer, "UTF-8");          fin.close();          }      catch(Exception e){          e.printStackTrace();      }      return res; }   

三、读写SD卡中的文件。也就是/mnt/sdcard/目录下面的文件 :

//写数据到SD中的文件public void writeFileSdcardFile(String fileName,String write_str) throws IOException{  try{        FileOutputStream fout = new FileOutputStream(fileName);        byte [] bytes = write_str.getBytes();        fout.write(bytes);        fout.close();      }      catch(Exception e){         e.printStackTrace();        }    }   //读SD中的文件public String readFileSdcardFile(String fileName) throws IOException{   String res="";   try{          FileInputStream fin = new FileInputStream(fileName);          int length = fin.available();          byte [] buffer = new byte[length];          fin.read(buffer);              res = EncodingUtils.getString(buffer, "UTF-8");          fin.close();             }         catch(Exception e){          e.printStackTrace();         }         return res; } 

四、使用File类进行文件的读写:

//读文件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 = EncodingUtils.getString(buffer, "UTF-8");          fis.close();              return res;  }  //写文件public void writeSDFile(String fileName, String write_str) throws IOException{          File file = new File(fileName);          FileOutputStream fos = new FileOutputStream(file);          byte [] bytes = write_str.getBytes();         fos.write(bytes);         fos.close(); } 

五、另外,File类还有下面一些常用的操作:

String Name = File.getName();  //获得文件或文件夹的名称:String parentPath = File.getParent();  //获得文件或文件夹的父目录String path = File.getAbsoultePath();//绝对路经String path = File.getPath();//相对路经 File.createNewFile();//建立文件  File.mkDir(); //建立文件夹  File.isDirectory(); //判断是文件或文件夹File[] files = File.listFiles();  //列出文件夹下的所有文件和文件夹名File.renameTo(dest);  //修改文件夹和文件名File.delete();  //删除文件夹或文件

六、使用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("复制完成!");   }  }  


七、读取资源文件时能否实现类似于seek的方式可以跳转到文件的任意位置,从指定的位置开始读取指定的字节数呢?

答案是可以的。

在FileInputStream和InputStream中都有下面的函数:

public long skip (long byteCount); //从数据流中跳过n个字节public int read (byte[] buffer, int offset, int length); //从数据流中读取length数据存在buffer的offset开始的位置。offset是相对于buffer的开始位置的,不是数据流。

可以使用这两个函数来实现类似于seek的操作,请看下面的测试代码:

//其中read_raw是一个txt文件,存放在raw目录下。//read_raw.txt文件的内容是:"ABCDEFGHIJKLMNOPQRST"public String getRawString() throws IOException {String str = null;InputStream in = getResources().openRawResource(R.raw.read_raw);int length = in.available();byte[] buffer = new byte[length];in.skip(2); //跳过两个字节in.read(buffer,0,3); //读三个字节in.skip(3); //跳过三个字节in.read(buffer,0,3); //读三个字节//最后str="IJK"str = EncodingUtils.getString(buffer, "BIG5");in.close();return str;}

从上面的实例可以看出skip函数有点类似于C语言中的seek操作,但它们之间有些不同。

需要注意的是:

1、skip函数始终是从当前位置开始跳的。在实际应用当中还要再判断一下该函数的返回值。

2、read函数也始终是当前位置开始读的。

3、另外,还可以使用reset函数将文件的当前位置重置为0,也就是文件的开始位置。


如何得到文件的当前位置?

我没有找到相关的函数和方法,不知道怎么样才能得到文件的当前位置,貌似它也并不是太重要。


八、如何从FileInputStream中得到InputStream?

public String readFileData(String fileName) throws IOException{   String res="";   try{          FileInputStream fin = new FileInputStream(fileName);  InputStream in = new BufferedInputStream(fin);         ...      }      catch(Exception e){          e.printStackTrace();       }}

九、APK资源文件的大小不能超过1M,如果超过了怎么办?我们可以将这个数据再复制到data目录下,然后再使用。复制数据的代码如下:

public boolean assetsCopyData(String strAssetsFilePath, String strDesFilePath){       boolean bIsSuc = true;       InputStream inputStream = null;       OutputStream outputStream = null;              File file = new File(strDesFilePath);       if (!file.exists()){           try {              file.createNewFile();              Runtime.getRuntime().exec("chmod 766 " + file);           } catch (IOException e) {              bIsSuc = false;           }                  }else{//存在           return true;       }              try {           inputStream = getAssets().open(strAssetsFilePath);           outputStream = new FileOutputStream(file);                      int nLen = 0 ;                      byte[] buff = new byte[1024*1];           while((nLen = inputStream.read(buff)) > 0){              outputStream.write(buff, 0, nLen);           }                      //完成       } catch (IOException e) {           bIsSuc = false;       }finally{           try {              if (outputStream != null){                  outputStream.close();              }                            if (inputStream != null){                  inputStream.close();              }           } catch (IOException e) {              bIsSuc = false;           }                  }              return bIsSuc;    }




转载时请注明出处:http://blog.csdn.net/ztp800201/article/details/7322110


总结:

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





更多相关文章

  1. React Native 调用原生Android/iOS代码实现拨号功能
  2. 布局中文件中【控件间距参数详解以及单位选择】
  3. Android文件操作中的openFileOutPut和openFileInput
  4. 浅谈android的selector,背景选择器
  5. Android(安卓)为什么使用DVM虚拟机,而不使用Java JVM??
  6. Android之NDK开发
  7. Pro Android(安卓)4 第三章 理解Android中的资源
  8. Android之Adapter用法总结
  9. Android(安卓)分析 Android(安卓)应用结构

随机推荐

  1. Android为textView设置setText的时候报错
  2. Android button原理 转载
  3. Android(安卓)DataBinding 双向数据绑定
  4. Android图片异步加载之Android-Universal
  5. Android(安卓)UI日志
  6. Android自动开关机实现
  7. React Native开发error calling appregis
  8. android平台下基于cmake编译链接ffmpeg-3
  9. 3D激光扫描三维重建——6.(android)系统框
  10. Android 项目实践(二)——网络连接