zoukankan      html  css  js  c++  java
  • 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 }
    复制代码

    说明: 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             // 将“换行符
    ”写入到输出流中
    42             out.write('
    ');
    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
    ", str);
    66     }
    67 }
    复制代码

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

  • 相关阅读:
    Eclipse CDT 调试故障解决:Can't find resource for bundle java.util.PropertyResourceBundle
    winpcap 枚举网卡设备Demo
    ORCA msi修改工具 解决 msn 卡巴斯基 iTune等不能在Windows Server 2003下安装的问题
    收藏 彩色转灰度的舍入问题
    C++之仿函数
    CTreeCtrl icon 背景透明 解决方法
    colinux 运行和配置
    生成COM Dll的tlb文件的两种方法
    windows下建立gcc/g++/gdb/make编译及调试C/C++的IDE环境
    使用伪寄存器调试MSVC++程序的介绍An introduction to debugging in MSVC++ using Pseudoregisters
  • 原文地址:https://www.cnblogs.com/shangxiaofei/p/3844065.html
Copyright © 2011-2022 走看看