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者交流!群成员职业不限,程序员居多,讨论主题不限:技术分享,生活感悟,职场心得,时事分析...

原文地址:https://www.cnblogs.com/idayln/p/3106487.html