Java基础之IO(4)-Writer

概述

上一篇讲得是Reader字符输入流,今天讲的是Writer字符输出流。同OutputStream类似,只是OutputStream输出的是字节,Writer输出的是字符。字节流和字符流不在这里介绍,前面已经讲得很多了。Writer的继承关系图

Alt

节点流

FileWriter

FileWriter是字符输出流,同FileReader一样是一种以操作字符的流。这里我们要明白,虽然这里我们输出的是字符,并不是写到文件里的就是字符,不管是字节流还是字符流,文件存储的都是字节。之所以FileWriter可以输出字符,是因为FileWriter继承至OutputStreamWriter,而OutputStreamWriter内部有一个StreamEncoder对象,StreamEncoder对象持有一个OutputStream对象,StreamEncoder的作用就是将字符按指定(或默认)的编码将字符编码为字节然后输出到OutputStream中。

  • FileWriter构造方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    FileWriter(File file)
    //用一个打开的文件描述符作为构造参数,数据将输出到该文件描述符对应的节点
    FileWriter(FileDescriptor fd)
    //append是否以追加的方式写,如果该参数为false,则文件会被覆盖,下边append同义
    FileWriter(File file, boolean append)
    //输出时指定字符编码,因为不像FileOutputStream输出的字节。
    //码,在输出字符时会按照该字符输出,同理在读取时也要采用对应的字符编码。
    FileWriter(File file, Charset charset)

    FileWriter(File file, Charset charset, boolean append)

    FileWriter(String fileName)

    FileWriter(String fileName, boolean append)

    FileWriter(String fileName, Charset charset)

    FileWriter(String fileName, Charset charset, boolean append)
  • FileWriter方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void flush()

    String getEncoding()

    void write(char[] cbuf, int off, int len)

    void write(int c)

    void write(String str, int off, int len)

    Writer append(char c)

    Writer append(CharSequence csq)

    Writer append(CharSequence csq, int start, int end)
    //关闭流,先刷新再关闭
    void close()

    void flush()
    //返回一个新的字符输出流,并丢弃之前写的字符
    static Writer nullWriter()
PipedWriter

前面讲过PipedOutputStream,PipiedWriter和PipedOutputStream类似,也不能单独起作用,需要和PipiedReader一起使用才能起作用。同样的线程通过向PipiedWriter写入字符,而PipedReader提供一个缓冲区,接收PipiedWriter写入的字符,然后从PipiedReader的缓冲区中读取出来。只是PipedOutputStream面向的是字节,而PipiedWriter面向字符。

  • 构造函数

    1
    2
    3
    PipedWriter()	

    PipedWriter(PipedReader snk)
  • 主要方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void close()

    void connect(PipedReader snk)

    void flush()

    void write(char[] cbuf, int off, int len)

    void write(int c)
  • 简单例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    public class PipedReaderDemo {
    public static void main(String[] args) {
    PipedReader pipedReader = new PipedReader();
    PipedWriter pipedWriter = new PipedWriter();
    try {
    pipedReader.connect(pipedWriter);
    } catch (IOException e) {
    e.printStackTrace();
    }

    ExecutorService executorService = Executors.newFixedThreadPool(2);
    executorService.execute(new Productor(pipedWriter));
    executorService.execute(new Consumer(pipedReader));
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    executorService.shutdown();
    }
    }

    class Productor implements Runnable{
    private PipedWriter pipedWriter;

    public Productor(PipedWriter pipedWriter){
    this.pipedWriter = pipedWriter;
    }
    @Override
    public void run() {
    String str = "你好";
    try {
    pipedWriter.write(str.toCharArray());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }

    class Consumer implements Runnable{
    private PipedReader pipedReader;

    public Consumer(PipedReader pipedReader){
    this.pipedReader = pipedReader;
    }
    @Override
    public void run() {
    char[] chars = new char[2];
    try {
    pipedReader.read(chars, 0, 2);
    System.out.println(chars);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
CharArrayWriter

CharArrayWriter和CharArrayReader类似,CharArrayReader是从CharArrayReader内部缓冲区中读取字符;CharArrayWriter是往CharArrayWriter内部的缓冲区中写字符,然后调用toCharArray方法可以得到缓冲区的之前写的所有字符。根据这个特性,可以用来缓存一些中间结果当不想把它写到磁盘上时。

  • 构造函数

    1
    2
    3
    CharArrayWriter()	

    CharArrayWriter(int initialSize)
  • 主要方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    CharArrayWriter append(char c)

    CharArrayWriter append(CharSequence csq)

    CharArrayWriter append(CharSequence csq, int start, int end)

    void close()

    void flush()

    void reset()

    int size()

    char[] toCharArray()

    String toString()

    void write(char[] c, int off, int len)

    void write(int c)

    void write(String str, int off, int len)

    void writeTo(Writer out
  • 简单例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class CharArrayWriterDemo {
    public static void main(String[] args) {
    //指定创建一个10字符的缓冲区
    CharArrayWriter charArrayWriter = new CharArrayWriter(10);

    charArrayWriter.append('你');
    charArrayWriter.append('好');
    try {
    FileWriter fileWriter = new FileWriter(FileDescriptor.out);
    charArrayWriter.write("啊");
    //将缓冲区所有字符输出到指定的Writer中,这里是将它输出到了终端输出
    charArrayWriter.writeTo(fileWriter);
    fileWriter.flush();
    } catch (IOException e) {
    e.printStackTrace();
    }
    System.out.println(charArrayWriter.toCharArray());
    }
    }

    输出结果

    1
    你好啊你好啊
StringWriter

StringWriter类是其回收在字符串缓冲区中的输出,那么它可以被用来构造一个字符串的字符流。关闭StringWriter没有任何作用。在这个类中的方法可以在后流已关闭,而不会产生一个IOException被调用。

  • 构造函数

    1
    2
    3
    StringWriter()	

    StringWriter(int initialSize)
  • 主要方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    StringWriter	append(char c)	

    StringWriter append(CharSequence csq)

    StringWriter append(CharSequence csq, int start, int end)

    void close()

    void flush()

    StringBuffer getBuffer()

    String toString()

    void write(char[] cbuf, int off, int len)

    void write(int c)

    void write(String str)

    void write(String str, int off, int len)

处理流

BufferedWriter

BufferedWriter和BufferedReader类似,增强了字符流的能力,为其提供缓冲的功能,我们不用在关心系统是如何将字符写入节点的,也可以通过flush函数手动将数据刷新至节点中。

  • 构造函数

    1
    2
    3
    BufferedWriter(Writer out)

    BufferedWriter(Writer out, int sz)
  • 主要方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //手动刷新将数据写入节点
    void flush()
    //另起一行
    void newLine()
    //将cbuf数组从off开始的len个字符写入输出流中
    void write(char[] cbuf, int off, int len)

    void write(int c)
    //将s字符串从off开始的len个字符写入输出流中
    void write(String s, int off, int len)
  • 简单例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class BufferedWriterDemo {
    public static void main(String[] args) {

    try (FileWriter fileWriter = new FileWriter("/tmp/test");
    BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)){
    // 当仅仅执行这一句的时候。打开文件还没有看到任何字符,
    // 这是因为写入的字符还不够触发flush
    bufferedWriter.write("你好啊 哈哈哈", 0, 3);
    // 当执行了这一句时,可以看到文件中有三个字符为“你好啊”
    bufferedWriter.flush();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
OutputStreamWriter

OutputStreamWriter是一个字符输出处理流,用于写出文本数据,OutputStreamWriter的最主要的特点就是可以将指定的字符串按照特定的字符集转换为字节流之后写出。前边说过的FileWriter便是继承该类,所以FIleWriter具有OutputStreamWriter的增强功能。

  • 构造函数

    1
    2
    3
    4
    5
    6
    7
    OutputStreamWriter(OutputStream out)

    OutputStreamWriter(OutputStream out, String charsetName)

    OutputStreamWriter(OutputStream out, Charset cs)

    OutputStreamWriter(OutputStream out, CharsetEncoder enc)
  • 方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void	flush()
    //获取当前流采用的编码格式
    String getEncoding()

    void write(char[] cbuf, int off, int len)

    void write(int c)

    void write(String str, int off, int len)
  • 简单例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class OutputStreamWriterDemo {
    public static void main(String[] args) {
    try (FileOutputStream fos = new FileOutputStream("/tmp/test");
    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8")) {
    // 按照UTF-8的编码格式输出到文件中,看了文件大小为9个字节
    osw.write("你好啊");
    //获取当前流采用的编码格式
    System.out.println(osw.getEncoding());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
PrintWriter

PrintWriter方法看似很多,其实都很简单,主要都是提供一些格式化输出的方法。

  • 构造函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    PrintWriter(File file)	

    PrintWriter(File file, String csn)

    PrintWriter(File file, Charset charset)

    PrintWriter(OutputStream out)

    PrintWriter(OutputStream out, boolean autoFlush)

    PrintWriter(OutputStream out, boolean autoFlush, Charset charset)

    PrintWriter(Writer out)

    PrintWriter(Writer out, boolean autoFlush)

    PrintWriter(String fileName)

    PrintWriter(String fileName, String csn)

    PrintWriter(String fileName, Charset charset)
  • 方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    PrintWriter	append(char c)	

    PrintWriter append(CharSequence csq)

    PrintWriter append(CharSequence csq, int start, int end)

    boolean checkError()

    protected void clearError()

    void close()

    void flush()

    PrintWriter format(String format, Object... args)

    PrintWriter format(Locale l, String format, Object... args)

    void print(boolean b)

    void print(char c)

    void print(char[] s)

    void print(double d)

    void print(float f)

    void print(int i)

    void print(long l)

    void print(Object obj)

    void print(String s)

    PrintWriter printf(String format, Object... args)

    PrintWriter printf(Locale l, String format, Object... args)

    void println()

    void println(boolean x)

    void println(char x)

    void println(char[] x)

    void println(double x)

    void println(float x)

    void println(int x)

    void println(long x)

    void println(Object x)

    void println(String x)

    protected void setError()

    void write(char[] buf)

    void write(char[] buf, int off, int len)

    void write(int c)

    void write(String s)

    void write(String s, int off, int len)