码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员——【Java基础】——Java IO流

时间:2014-10-03 01:57:23      阅读:351      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   os   使用   ar   java   for   

一、IO概述

  1、IO:是Input、Output的缩写。

  2、特点:

  (1)用于处理设备间的数据传输。

  (2)Java对数据的处理是通过“流”完成的。

  (3)Java用于操作流的对象都在IO包中。

  (4)流按操作分为两种:字节流和字符流。

  (5)流按流向分为:输入流和输出流(输入输出是相对于“内存”而言的)。

  3、IO流常用基类

  (1)字节流abstract基类:InputStream、OutputStream;

  (2)字符流抽象基类:Reader、Writer;

二、字符流(Reader、Writer

  (一)概述

  字符流只用于处理文字数据,是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。简单说:字符流 = 字节流+编码表

  (二)写入字符流(Writer

  1、“写入字符流”操作步骤

  (1)创建时,要明确文件存储路径。如果文件不存在,则自动创建文件。如果文件存在,则会覆盖原文件。代码示例:

    FileWtriter fw = new FileWriter("d:\\d.txt");

  (2)调用Writer对象中的write(String s)方法,将数据写入到“临时存储缓冲区”中。代码示例:

    fw.write("abcde");

  (3)调用flush()方法,刷新该流的缓冲,将数据刷新到目的地中。代码示例:

    fw.flush(); //可以用多次

  (4)调用close()方法,关闭流资源。代码示例:

    fw.close();//但是关闭前会刷新一次内部的缓冲数据,并将数据刷新到目的地中,只能用一次。

  注意:close()和flush()区别:flush()刷新后,流可以继续使用;而close()刷新后,将会关闭流,不可再写入字符流。

  2、FileWriter细节

  (1)换行

  Windows系统中的换行是\r\n,而Linux系统中的换行是\n。为了能够适应不同的操作系统,java可以获取系统换行。格式如下

    System.getProperty(“line.sepatator”);

  (2)续写

  如果再FileWriter的构造函数中加入true,可以实现对文件实行续写。格式如下:

    FileWtriter fw = new FileWriter("d:\\d.txt" , true);

  (3)IO异常处理

  将FileWriter对象(FileWriter fw = null)声明在try{}catch(){}外面。

  在finally中,关闭流对象,判断fw是否为空,不为空时,才可以用try{}catch(){}来处理fw.close()。否则,会出现java.lang.NullPointerException。

  3、FileWriter总结

  (1)其实java自身不能写入数据,而是调用系统内部方式完成数据的书写,使用系统资源后,一定要关闭资源。

  (2)文件的数据的续写是通过构造函数 FileWriter(Strings,boolean append),在创建对象时,传递一个true参数,代表不覆盖已有的文件。并在已有文件的末尾处进行数据续写。(windows系统中的文件内换行用\r\n两个转义字符表示,在linux系统中只用\n表示换行)

  (3)由于在创建对象时,需要指定创建文件位置,如果指定的位置不存在,就会发生IOException异常,所以在整个步骤中,需要对IO异常进行try处理。

  (三)读取字符流(Reader

  1、“读取字符流”操作步骤

  (1)创建一个文件读取流对象,和指定名称的文件相关联。要保证该文件已经存在,若不存在,将会发生异常FileNotFoundException。代码示例:

    FileReader fr = new FileReader(“d:\\demo.txt”);

  (2)调用读取流对象的read()方法。read()有两种读取方式:一种是读取单个字符。另一种是通过字符数组进行读取。两种读取方式的代码示例:

    ① 读取单个字符方式:int ch = fr.read();

    ② 读取字符数组方式: 

1 char[] buf = new char[1024];
2 Int len = 0;
3 While(( len = fr.read(buf))!=-1){
4     System.out.print( new String(buf , 0 , len));
5 }

  (3)读取后调用close()方法,关闭流资源。代码示例:

    fr.close();

  2、FileReader总结

  (1)定义文件路径时,可以用“/”或者“\\”。

  (2)在创建一个文件时,如果目录下有同名文件将被覆盖。

  (3)在读取文件时,必须保证该文件已存在,否则出异常。

  (四)字符流练习:

  /*

  需求:将c盘一个文本文件复制到d盘。

  思路:1、需要读取源;2、将读到的源写入到目的地;

  步骤:

  1、读一个文件,是字符读取流和文件关联;

  2、创建一个目的文件,用于存储读到的数据;

  3、频繁的读写;

  4、关闭流资源;

  */

 1 import java.io.*;
 2 class ReaderWriterTest {
 3     public static void main(String[] args) {
 4         // 调用复制方法
 5         // copy_1();
 6         copy_2();
 7     }
 8     // 用第一种读取方式进行复制
 9     public static void copy_1() {
10         FileWriter fw = null;
11         FileReader fr = null;
12         try {
13             // 关联读取和写入的文件
14             fw = new FileWriter("D:\\HelloWorld.java");
15             fr = new FileReader("C:\\HelloWorld.java");
16             for (int ch = 0; (ch = fr.read()) != -1;) {
17                 fw.write(ch);// 一个字符一个字符写入
18             }
19         } catch (IOException e) {
20             throw new RuntimeException("读写失败");
21         } finally {
22             if (fr != null)
23                 try {
24                     fr.close();// 对读取流和写入流分别关闭
25                 } catch (IOException e) {
26                 }
27             if (fw != null)
28                 try {
29                     fw.close();
30                 } catch (IOException e) {
31                 }
32         }
33     }
34     // 第二种读取方式进行复制
35     public static void copy_2() {
36         FileWriter fw = null;
37         FileReader fr = null;
38         try {
39             // 关联读取和写入的文件
40             fw = new FileWriter("D:\\HelloWorld.java");
41             fr = new FileReader("C:\\HelloWorld.java");
42             char[] arr = new char[1024];
43             for (int len = 0; (len = fr.read(arr)) != -1;) {
44                 fw.write(arr, 0, len);// 利用数组一次存入数组中的字符
45             }
46         } catch (IOException e) {
47             throw new RuntimeException("读写失败");
48         } finally {
49             try {
50                 if (fr != null)
51                     fr.close();
52             } catch (IOException e) {
53             } finally {
54                 if (fw != null)
55                     try {
56                         fw.close();
57                     } catch (IOException e) {
58                     }
59             }
60         }
61     }
62 }

三、字符流缓冲区

  (一)概述

  1、字符流缓冲区的作用:提高了对数据的读写效率。

  2、对应的类:BufferedWriter以及BufferedReader,要结合流,才可以使用。

  (二)BufferedWriter

  1、操作步骤

  (1)创建一个字符写入流对象,代码示例:

    FileWriter fw = new FileWriter("demo.txt");

  (2)为了提高字符写入流效率,加入缓冲技术,将需要被提高效率的流对象作为参数传递给缓冲区的构造函数,代码示例:

    BufferedWriter bufw = new BufferedWriter(fw);

  (3)调用write方法写入数据到指定文件,代码示例:

    bufw.write ("abcde");

  (4)刷新缓冲区,代码示例:

    bufw.flush();

  (5)关闭流资源,,代码示例:

    bufw.close();

  2、小细节:BufferedWriter提供了跨平台的换行符newLine()方法,格式:bufw.newLine();

  (三)BufferedReader

  1、作用

  从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

  2、特点

  BufferedReader提供了一次读一行的方法readLine(),方便于文本数据的获取,当返回null时表示读到文件末尾。readLine方法返回的时候,只返回回车符之前的数据内容。并不返回回车符。

  3、readLine()原理

  使用了读取缓冲区的read()方法,将读取到的字符进行缓冲并判断换行标记,将标记前的缓存数据变成字符串返回。

  4、BufferedReader操作步骤

  (1)创建一个读取流对象和文件相关联,

    FileReader fr = new FileReader("demo.txt");

  (2)为了提高效率、加入缓冲技术、将字符读取流对象作为参数传递给缓冲区对象的构造函数。

    BufferedReader bufr = new BufferedReader(fr);

  (3)调用该readLine()方法一行一行读取,如果到达文件末尾,则返回null

    String str = bufr.readLine();

  (4)关闭流资源

    bufr.close();

  (四)练习

  /* 需求:使用缓冲技术copy一个文本文件 */ 

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyTextByBufTest {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("buf.txt");
        BufferedReader bufr = new BufferedReader(fr);
        FileWriter fw = new FileWriter("buf_copy.txt");
        BufferedWriter bufw = new BufferedWriter(fw);
        String line = null;
        while((line=bufr.readLine())!=null){
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
        }
//单个字符读取方式
        //int ch = 0;
        //while((ch=bufr.read())!=-1){
        //    bufw.write(ch);
        //}
        bufw.close();
        bufr.close();
    }
}

  (五)自定义缓冲区

 1 /*需求:模拟BufferedReader,自定义一个MyBufferedReader缓冲区 */
 2 import java.io.*;
 3 //自定义缓冲类  
 4 class MyBufferedReader extends Reader {
 5     private Reader r;// 定义接收的流对象
 6     MyBufferedReader(Reader r) {
 7         this.r = r;
 8     }
 9     // 自定义整行读取
10     public String myReadLine() throws IOException {
11         // 创建一个容器,用来存储一行的字符
12         StringBuilder sb = new StringBuilder();
13         // 一个字符一个字符读取
14         for (int ch = 0; (ch = r.read()) != -1;) {
15             if (ch == ‘\r‘)// 如果遇到换行符,则继续
16                 continue;
17             if (ch == ‘\n‘)// 如果遇到回车符,表示该行读取完毕
18                 return sb.toString();
19             else
20                 sb.append((char) ch);// 将该行的字符添加到容器
21         }
22         if (sb.length() != 0)// 如果读取结束,容器中还有字符,则返回元素
23             return sb.toString();
24         return null;
25     }
26     // 复写父类中的抽象方法
27     public int read(char[] cbuf, int off, int len) throws IOException {
28         return r.read(cbuf, off, len);
29     }
30     // 复写父类的close方法
31     public void close() throws IOException {
32         r.close();
33     }
34 }
35 
36 // 测试MyBufferedReader
37 class MyBufferedReaderDemo {
38     public static void main(String[] args) {
39         MyBufferedReader mbr = null;
40         try {
41             mbr = new MyBufferedReader(new FileReader("d:\\HelloWorld.java"));
42             for (String line = null; (line = mbr.myReadLine()) != null;) {
43                 System.out.println(line);// 显示效果
44             }
45         } catch (IOException e) {
46             throw new RuntimeException("读取数据失败");
47         } finally {
48             try {
49                 if (mbr != null)
50                     mbr.close();
51             } catch (IOException e) {
52                 throw new RuntimeException("读取流关闭失败");
53             }
54         }
55     }
56 }

  (六)LineNumberReader

  在BufferedReader中有个直接的子类LineNumberReader,其中有特有的方法获取和设置行号:

  setLineNumber();//设置初始行号

  getLineNumber();//获取行号

  (七)装饰设计模式

  1、对一组对象的功能进行增强时,就可以使用装饰模式来解决问题。

  2、特点:装饰类通常都会通过构造方法接收被装饰的对象,基于被装饰的对象的功能,提供更强的功能。

  3、“装饰和继承”的异同?

  (1)相同点:进行功能的扩展和增强,

  (2)区别:装饰模式比继承要灵活、避免了继承体系的臃肿,降低了类与类之间的继承关系。装饰类和被装饰的类通常都是属于一个体系,有同一个接口或父类。

  注:在定义类的时候,不要以继承为主;可通过装饰设计模式进行增强类功能。灵活性较强,当装饰类中的功能不适合,可再使用被装饰类的功能。

 

 

 

 

黑马程序员——【Java基础】——Java IO流

标签:style   blog   color   io   os   使用   ar   java   for   

原文地址:http://www.cnblogs.com/jianxingjianyuan2014/p/4004621.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!