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”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM