zoukankan      html  css  js  c++  java
  • Android开发之I/O流下篇

      在上篇中,已经写下了IO流概念以及对File类操作,如果想查阅上篇的内容,请点击这里: http://www.cnblogs.com/idayln/archive/2013/05/27/3102810.html . 此文是它的姊妹篇!本文以Demo为主,不会涉及太多概念!!!

    • 输入流: InputStream/Reader 拥有一系列read方法
      • InputStream 是字节输入流的超类
      • Reader是字符输入流的超类
    • 输出流: OutputStream/Writer 拥有一系列write方法
      • OutputStream 字节输出类的超类
      • Writer 字符输出流的超类

    输出流代码:

    1 static void demo0() throws Exception {
    2         try (OutputStream outputStream = new FileOutputStream("demo1.txt")) {
    3             outputStream.write("First 'demo' for how to use 'OutputStream' !"
    4                     .getBytes());
    5         }
    6         System.out.println("Over");
    7     }

    看到这段代码,是不是感觉有点奇怪?别紧张.

    1. 上段代码是Java 7中异常新特性:try-with-resources: 它可以自行进行资源管理,例如上例就不需要手动close;需要注意的是:try(/* 此处可以是代码块 */),这种语法节省的好多代码。
    2. OutputStream是个抽象类,它必须通过子类来进行实例化。
    3. OutputStream主要分为二种功能
      1. 字入数据的write系列方法
        1. 参数为byte: 单一字节
        2. 参数为byte数组
        3. 参数为byte数组和数组中的起始位置与长度
      2. 流的控制
        1. 关闭:close
        2. 刷新保存:flush: 其实不必手动flush。第一:当内部缓冲期满过,它会自动自动执行flush;第二:当invoke close方法时,会自动执行flush。

    输入流代码:

     1 static void demo1() throws IOException{
     2         InputStream inputStream =null;
     3         try {
     4             inputStream = new FileInputStream("demo0.txt");
     5             byte[] bb = new byte[1024];  //缓冲区
     6             int temp;
     7             while((temp=inputStream.read(bb))!=-1){
     8                 System.out.println(new String(bb, 0, temp));
     9             }
    10         } catch (FileNotFoundException e) {
    11             // TODO Auto-generated catch block
    12             e.printStackTrace();
    13         }finally{
    14             if(inputStream!=null){
    15                 inputStream.close();
    16             }
    17         }
    18     }

     InputStream:

    1. 上段采用Java 6的语法,是不是明显感觉到代码量增多:从7行增加到18行。
    2. 与OutputStream一样是个抽象类。因为它们都是比较早设计的类,因此并没有采用流行的面向接口编程思想。
    3. 与OutputStream一样也主要有二个功能:read系列方法,但是它的流的控制没有flush而是添加了skip,mark这二个方法,平时用得少,感兴趣的同学可以自行去查API。

    Reader,Writer与InputStream,OutputStream基本功能相,这里就不在解释。深入理解了InputStream与OutputStream之后,学其它就很快;对于不同的处理流,查API就行!!

    附上IO流体系结构表:

    IO流体系结构
    分类 字节输入流 字节输出流 字符输入流 字符输出流
    抽象基类 InputStream OutputSteam Reader Writer
    文件 FileInputStream FileOutputSteam FileReader FileWriter
    数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
    缓冲 BufferedInputStream  BufferedOutputStream BufferdReader

    BufferWriter  

    对象 ObjectInputStream ObjectOutputStream    
    转换     InputStreamReader OutputStreamWriter
    打印   PrintStream   PrintWriter
    字符串     StringReader StringWriter
    管道 PipedInputStream PipedOutputStream PipedReader PipedWriter

    这多类,该如何记忆,理解呢? 我是这么理解的。

    首先把它们大致划分为:节点流与处理流。节点流就是直接与物理节点,进行交互;而处理流通常直接处理的对象是节点流,是再上一层的包装。

    比如:如果想对read操作进行同步缓冲,可以使用BufferedInputStream:

     1 static void demo2() throws Exception{
     2         InputStream inputStream =null;
     3         BufferedInputStream bufferedInputStream =null;
     4         try {
     5             inputStream = new FileInputStream("demo0.txt");
     6             bufferedInputStream = new BufferedInputStream(inputStream);
     7             byte[] bb = new byte[1024];
     8             int temp=-1;
     9             while((temp=bufferedInputStream.read(bb))!=-1){
    10                 System.out.println(new String(bb,0,temp));
    11             }
    12         } catch (FileNotFoundException e) {
    13             // TODO Auto-generated catch block
    14             e.printStackTrace();
    15         }finally{
    16             if(inputStream!=null){
    17                 inputStream.close();
    18             }
    19         }
    20     }

    RandomAccessFile: 任意访问内容类:既可以读取文件内容,也可以向文件输出数据,可以自由访问文件的任意位置,它可以自由定位文件记录指针。

    二个重要方法:

    1. long getFilePointer(): 获取文件记录的当前指针位置
    2. void seek(long position): 将文件的记录指针特定position的位置。

    使用RandomAccessFile 必须要设置模式:

    1. r: 只读
    2. rw: 读写,如果不存在,则自动创建。
    3. rws: 读写,读文件内容与元数据改动都会同步更新到Target Device上;
    4. rwd:与rws类似,差别在于,当元数据改动后,不会同步更新到Target Device
     1 static void demo3() throws Exception{
     2         RandomAccessFile file = new RandomAccessFile("demo0.txt", "rw");
     3         System.out.println("Before invoke write:"+file.getFilePointer());
     4         file.seek(file.length());
     5         file.write("\nUsing RandomAccessFile Class".getBytes());
     6         
     7         System.out.println("After invoke write:"+file.getFilePointer());
     8         file.seek(0);
     9         byte[] bb = new byte[1024];
    10         int temp=-1;
    11         while ((temp=file.read(bb))>0) {
    12             System.out.println(new String(bb,0,temp));    
    13         }
    14         
    15         file.close();
    16     }

    如果要在指定的位置进行插入内容,那必须得把指定位置的内容进行缓存,不然会被替代。

     1 static void demo4(String fileName,long position,String content) throws Exception{
     2         RandomAccessFile file = new RandomAccessFile(fileName, "rws");
     3         File tempFile = File.createTempFile("temp", null);
     4         
     5         long currentLength = file.length();
     6         if(position>currentLength){
     7             return;
     8             //Maybe you can setup position=currentLenght; Also you can setup anything what you want !!!
     9         }
    10         FileOutputStream fileOutputStream = new FileOutputStream(tempFile); // write data to "temp" file 
    11         FileInputStream fileInputStream = new FileInputStream(tempFile); // read data 
    12         byte[] bb = new byte[512];
    13         int tempNum=-1;
    14         
    15         file.seek(position);
    16         
    17         while((tempNum=file.read(bb))>0){
    18             fileOutputStream.write(bb, 0, tempNum);
    19         }
    20         
    21         file.seek(position); // Go back to position
    22         file.write(content.getBytes());
    23         
    24         while((tempNum=fileInputStream.read(bb))>0){
    25             file.write(bb, 0, tempNum);
    26         }
    27         
    28         tempFile.deleteOnExit();
    29         if(fileInputStream!=null){
    30             fileInputStream.close();
    31         }
    32         if(fileOutputStream!=null){
    33             fileOutputStream.close();
    34         }
    35         
    36         file.close();
    37     }






    【Dylan童鞋】

    关注Dylan童鞋,请搜索微信号:DylanTongXue 。
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Q群:315858410. 此群用于关注DylanTongXue者交流!群成员职业不限,程序员居多,讨论主题不限:技术分享,生活感悟,职场心得,时事分析...

  • 相关阅读:
    (四十九)Quartz2D自定义控件
    (四十八)Quartz2D引擎进阶
    (四十七)Quartz2D引擎初步
    (四十六)内存管理的复习
    (四十五)Modal 模态窗口 -遮盖
    (四十四)TabBarController和NagivationController配合
    (四十三)UITabBarController和AppDelegate的一些细节
    (四十二)tableView的滑动编辑和刷新 -局部刷新和删除刷新 -待解决问题
    linux命令——svn分支创建、合并
    C++异常处理
  • 原文地址:https://www.cnblogs.com/idayln/p/3106487.html
Copyright © 2011-2022 走看看