java io系列24之 BufferedWriter(字符缓冲输出流)

转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_24.html

更多内容请参考:java io系列01之 "目录"

BufferedWriter 介绍

BufferedWriter 是缓冲字符输出流。它继承于Writer。
BufferedWriter 的作用是为其他字符输出流添加一些缓冲功能。

BufferedWriter 函数列表

// 构造函数
BufferedWriter(Writer out) 
BufferedWriter(Writer out, int sz) 
 
void    close()                              // 关闭此流,但要先刷新它。
void    flush()                              // 刷新该流的缓冲。
void    newLine()                            // 写入一个行分隔符。
void    write(char[] cbuf, int off, int len) // 写入字符数组的某一部分。
void    write(int c)                         // 写入单个字符。
void    write(String s, int off, int len)    // 写入字符串的某一部分。

 

BufferedWriter 源码分析(基于jdk1.7.40)

  1 package java.io;
  2 
  3 public class BufferedWriter extends Writer {
  4 
  5     // 输出流对象
  6     private Writer out;
  7 
  8     // 保存“缓冲输出流”数据的字符数组
  9     private char cb[];
 10 
 11     // nChars 是cb缓冲区中字符的总的个数
 12     // nextChar 是下一个要读取的字符在cb缓冲区中的位置
 13     private int nChars, nextChar;
 14 
 15     // 默认字符缓冲区大小
 16     private static int defaultCharBufferSize = 8192;
 17 
 18     // 行分割符
 19     private String lineSeparator;
 20 
 21     // 构造函数,传入“Writer对象”,默认缓冲区大小是8k
 22     public BufferedWriter(Writer out) {
 23         this(out, defaultCharBufferSize);
 24     }
 25 
 26     // 构造函数,传入“Writer对象”,指定缓冲区大小是sz
 27     public BufferedWriter(Writer out, int sz) {
 28         super(out);
 29         if (sz <= 0)
 30             throw new IllegalArgumentException("Buffer size <= 0");
 31         this.out = out;
 32         cb = new char[sz];
 33         nChars = sz;
 34         nextChar = 0;
 35 
 36         lineSeparator = java.security.AccessController.doPrivileged(
 37             new sun.security.action.GetPropertyAction("line.separator"));
 38     }
 39 
 40     // 确保“BufferedWriter”是打开状态
 41     private void ensureOpen() throws IOException {
 42         if (out == null)
 43             throw new IOException("Stream closed");
 44     }
 45 
 46     // 对缓冲区执行flush()操作,将缓冲区的数据写入到Writer中
 47     void flushBuffer() throws IOException {
 48         synchronized (lock) {
 49             ensureOpen();
 50             if (nextChar == 0)
 51                 return;
 52             out.write(cb, 0, nextChar);
 53             nextChar = 0;
 54         }
 55     }
 56 
 57     // 将c写入到缓冲区中。先将c转换为char,然后将其写入到缓冲区。
 58     public void write(int c) throws IOException {
 59         synchronized (lock) {
 60             ensureOpen();
 61             // 若缓冲区满了,则清空缓冲,将缓冲数据写入到输出流中。
 62             if (nextChar >= nChars)
 63                 flushBuffer();
 64             cb[nextChar++] = (char) c;
 65         }
 66     }
 67 
 68     // 返回a,b中较小的数
 69     private int min(int a, int b) {
 70         if (a < b) return a;
 71         return b;
 72     }
 73 
 74     // 将字符数组cbuf写入到缓冲中,从cbuf的off位置开始写入,写入长度是len。
 75     public void write(char cbuf[], int off, int len) throws IOException {
 76         synchronized (lock) {
 77             ensureOpen();
 78             if ((off < 0) || (off > cbuf.length) || (len < 0) ||
 79                 ((off + len) > cbuf.length) || ((off + len) < 0)) {
 80                 throw new IndexOutOfBoundsException();
 81             } else if (len == 0) {
 82                 return;
 83             }
 84 
 85             if (len >= nChars) {
 86                 /* If the request length exceeds the size of the output buffer,
 87                    flush the buffer and then write the data directly.  In this
 88                    way buffered streams will cascade harmlessly. */
 89                 flushBuffer();
 90                 out.write(cbuf, off, len);
 91                 return;
 92             }
 93 
 94             int b = off, t = off + len;
 95             while (b < t) {
 96                 int d = min(nChars - nextChar, t - b);
 97                 System.arraycopy(cbuf, b, cb, nextChar, d);
 98                 b += d;
 99                 nextChar += d;
100                 if (nextChar >= nChars)
101                     flushBuffer();
102             }
103         }
104     }
105 
106     // 将字符串s写入到缓冲中,从s的off位置开始写入,写入长度是len。
107     public void write(String s, int off, int len) throws IOException {
108         synchronized (lock) {
109             ensureOpen();
110 
111             int b = off, t = off + len;
112             while (b < t) {
113                 int d = min(nChars - nextChar, t - b);
114                 s.getChars(b, b + d, cb, nextChar);
115                 b += d;
116                 nextChar += d;
117                 if (nextChar >= nChars)
118                     flushBuffer();
119             }
120         }
121     }
122 
123     // 将换行符写入到缓冲中
124     public void newLine() throws IOException {
125         write(lineSeparator);
126     }
127 
128     // 清空缓冲区数据
129     public void flush() throws IOException {
130         synchronized (lock) {
131             flushBuffer();
132             out.flush();
133         }
134     }
135 
136     public void close() throws IOException {
137         synchronized (lock) {
138             if (out == null) {
139                 return;
140             }
141             try {
142                 flushBuffer();
143             } finally {
144                 out.close();
145                 out = null;
146                 cb = null;
147             }
148         }
149     }
150 }
View Code

说明: BufferedWriter的源码非常简单,这里就BufferedWriter的思想进行简单说明:BufferedWriter通过字符数组来缓冲数据,当缓冲区满或者用户调用flush()函数时,它就会将缓冲区的数据写入到输出流中。

 

示例代码

关于BufferedWriter中API的详细用法,参考示例代码(BufferedWriterTest.java):

 1 import java.io.BufferedWriter;
 2 import java.io.File;
 3 import java.io.OutputStream;
 4 import java.io.FileWriter;
 5 import java.io.IOException;
 6 import java.io.FileNotFoundException;
 7 import java.lang.SecurityException;
 8 import java.util.Scanner;
 9 
10 /**
11  * BufferedWriter 测试程序
12  *
13  * @author skywang
14  */
15 public class BufferedWriterTest {
16 
17     private static final int LEN = 5;
18     // 对应英文字母“abcdefghijklmnopqrstuvwxyz”
19     //private static final char[] ArrayLetters = "abcdefghijklmnopqrstuvwxyz";
20     private static final char[] ArrayLetters = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
21 
22     public static void main(String[] args) {
23         testBufferedWriter() ;
24     }
25 
26     /**
27      * BufferedWriter的API测试函数
28      */
29     private static void testBufferedWriter() {
30 
31         // 创建“文件输出流”对应的BufferedWriter
32         // 它对应缓冲区的大小是16,即缓冲区的数据>=16时,会自动将缓冲区的内容写入到输出流。
33         try {
34             File file = new File("bufferwriter.txt");
35             BufferedWriter out =
36                   new BufferedWriter(
37                       new FileWriter(file));
38 
39             // 将ArrayLetters数组的前10个字符写入到输出流中
40             out.write(ArrayLetters, 0, 10);
41             // 将“换行符\n”写入到输出流中
42             out.write('\n');
43 
44             out.flush();
45             //readUserInput() ;
46 
47             out.close();
48        } catch (FileNotFoundException e) {
49            e.printStackTrace();
50        } catch (SecurityException e) {
51            e.printStackTrace();
52        } catch (IOException e) {
53            e.printStackTrace();
54        }
55     }
56 
57     /**
58      * 读取用户输入
59      */
60     private static void readUserInput() {
61         System.out.println("please input a text:");
62         Scanner reader=new Scanner(System.in);
63         // 等待一个输入
64         String str = reader.next();
65         System.out.printf("the input is : %s\n", str);
66     }
67 }

运行结果
生成文件“bufferwriter.txt”,文件的内容是“abcdefghij”。

你可能感兴趣的:(java io系列24之 BufferedWriter(字符缓冲输出流))