zoukankan      html  css  js  c++  java
  • Android

    复制自:http://blog.csdn.net/ztp800201/article/details/7322110

    十分感谢原作者!

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

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

    一、资源文件的读取:

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

     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 = EncodingUtils.getString(buffer, "BIG5"); 
    17     
    18     //关闭    
    19     in.close();            
    20 
    21    }catch(Exception e){ 
    22       e.printStackTrace();         
    23    } 

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

     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 = EncodingUtils.getString(buffer, "UTF-8");     
    14 
    15   }catch(Exception e){ 
    16 
    17       e.printStackTrace();         
    18 
    19    } 

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

     1 //写数据
     2 public void writeFile(String fileName,String writestr) throws IOException{ 
     3   try{ 
     4 
     5         FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE); 
     6 
     7         byte [] bytes = writestr.getBytes(); 
     8 
     9         fout.write(bytes); 
    10 
    11         fout.close(); 
    12       } 
    13 
    14         catch(Exception e){ 
    15         e.printStackTrace(); 
    16        } 
    17 } 
    18 
    19 //读数据
    20 public String readFile(String fileName) throws IOException{ 
    21   String res=""; 
    22   try{ 
    23          FileInputStream fin = openFileInput(fileName); 
    24          int length = fin.available(); 
    25          byte [] buffer = new byte[length]; 
    26          fin.read(buffer);     
    27          res = EncodingUtils.getString(buffer, "UTF-8"); 
    28          fin.close();     
    29      } 
    30      catch(Exception e){ 
    31          e.printStackTrace(); 
    32      } 
    33      return res; 
    34 
    35 }   

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

     1 //写数据到SD中的文件
     2 public void writeFileSdcardFile(String fileName,String write_str) throws IOException{ 
     3  try{ 
     4 
     5        FileOutputStream fout = new FileOutputStream(fileName); 
     6        byte [] bytes = write_str.getBytes(); 
     7 
     8        fout.write(bytes); 
     9        fout.close(); 
    10      }
    11 
    12       catch(Exception e){ 
    13         e.printStackTrace(); 
    14        } 
    15    } 
    16 
    17   
    18 //读SD中的文件
    19 public String readFileSdcardFile(String fileName) throws IOException{ 
    20   String res=""; 
    21   try{ 
    22          FileInputStream fin = new FileInputStream(fileName); 
    23 
    24          int length = fin.available(); 
    25 
    26          byte [] buffer = new byte[length]; 
    27          fin.read(buffer);     
    28 
    29          res = EncodingUtils.getString(buffer, "UTF-8"); 
    30 
    31          fin.close();     
    32         } 
    33 
    34         catch(Exception e){ 
    35          e.printStackTrace(); 
    36         } 
    37         return res; 
    38 } 

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

     1 //读文件
     2 public String readSDFile(String fileName) throws IOException {  
     3 
     4         File file = new File(fileName);  
     5 
     6         FileInputStream fis = new FileInputStream(file);  
     7 
     8         int length = fis.available(); 
     9 
    10          byte [] buffer = new byte[length]; 
    11          fis.read(buffer);     
    12 
    13          res = EncodingUtils.getString(buffer, "UTF-8"); 
    14 
    15          fis.close();     
    16          return res;  
    17 }  
    18 
    19 //写文件
    20 public void writeSDFile(String fileName, String write_str) throws IOException{  
    21 
    22         File file = new File(fileName);  
    23 
    24         FileOutputStream fos = new FileOutputStream(file);  
    25 
    26         byte [] bytes = write_str.getBytes(); 
    27 
    28         fos.write(bytes); 
    29 
    30         fos.close(); 
    31 } 

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

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

    六、使用RandomAccessFile进行文件的读写:

    RandomAccessFile的使用方法比较灵活,功能也比较多,可以使用类似seek的方式可以跳转到文件的任意位置,从文件指示器当前位置开始读写。
    它有两种构造方法
    new RandomAccessFile(f,"rw");//读写方式
    new RandomAccessFile(f,"r");//只读方式
    使用事例:

     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 }  

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

    答案是可以的。

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

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

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

     1 //其中read_raw是一个txt文件,存放在raw目录下。
     2 //read_raw.txt文件的内容是:"ABCDEFGHIJKLMNOPQRST"
     3 public String getRawString() throws IOException {
     4     
     5     String str = null;
     6     
     7     InputStream in = getResources().openRawResource(R.raw.read_raw);
     8     
     9     int length = in.available();
    10     byte[] buffer = new byte[length];
    11     
    12     in.skip(2); //跳过两个字节
    13     in.read(buffer,0,3); //读三个字节
    14     
    15     in.skip(3); //跳过三个字节
    16     in.read(buffer,0,3); //读三个字节
    17     
    18     //最后str="IJK"
    19     str = EncodingUtils.getString(buffer, "BIG5");
    20     
    21     
    22     in.close();
    23     
    24     return str;
    25 }

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

    需要注意的是:

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

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

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


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

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


    八、如何从FileInputStream中得到InputStream?

     1 public String readFileData(String fileName) throws IOException{ 
     2   String res=""; 
     3   try{ 
     4          FileInputStream fin = new FileInputStream(fileName); 
     5      InputStream in = new BufferedInputStream(fin);
     6 
     7          ...
     8 
     9       }
    10       catch(Exception e){ 
    11          e.printStackTrace(); 
    12       }
    13 }

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

     1     public boolean assetsCopyData(String strAssetsFilePath, String strDesFilePath){
     2            boolean bIsSuc = true;
     3            InputStream inputStream = null;
     4            OutputStream outputStream = null;
     5            
     6            File file = new File(strDesFilePath);
     7            if (!file.exists()){
     8                try {
     9                   file.createNewFile();
    10                   Runtime.getRuntime().exec("chmod 766 " + file);
    11                } catch (IOException e) {
    12                   bIsSuc = false;
    13                }
    14                
    15            }else{//存在
    16                return true;
    17            }
    18            
    19            try {
    20                inputStream = getAssets().open(strAssetsFilePath);
    21                outputStream = new FileOutputStream(file);
    22                
    23                int nLen = 0 ;
    24                
    25                byte[] buff = new byte[1024*1];
    26                while((nLen = inputStream.read(buff)) > 0){
    27                   outputStream.write(buff, 0, nLen);
    28                }
    29                
    30                //完成
    31            } catch (IOException e) {
    32                bIsSuc = false;
    33            }finally{
    34                try {
    35                   if (outputStream != null){
    36                       outputStream.close();
    37                   }
    38                   
    39                   if (inputStream != null){
    40                       inputStream.close();
    41                   }
    42                } catch (IOException e) {
    43                   bIsSuc = false;
    44                }
    45                
    46            }
    47            
    48            return bIsSuc;
    49         }    


    转载时请注明出处: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)函数来实现文件的随机读取。

    6.RandomAccessFile不能读取Assets下的文件

  • 相关阅读:
    Java子类和父类之间方法和属性关系
    静态链接库与动态链接库
    两人相遇问题时间段
    try catch finally
    shell判断条件参数过多
    python C++ Java 文件数据库等流操作,当打开后必须关闭
    CSS3 target 伪类不得不说那些事儿(纯CSS实现tab切换)
    清浮动方法
    this函数的理解
    css3 tranform  transition animation
  • 原文地址:https://www.cnblogs.com/mushui/p/3346473.html
Copyright © 2011-2022 走看看