15.3.2 OutputStream和Writer

15.3.2 OutputStream和Writer

OutputStreamWriter也非常相似,它们采用如图15.6所示的模型来执行输出,两个流都提供了如下三个方法

OutputStream的write方法

方法 描述
abstract void write(int b) 将指定的字节输出到输出流中,其中c既可以代表字节
void write(byte[] b) 将字节数组中的数据输出到指定输出流中。
void write(byte[] b, int off, int len) 将字节数组中从off位置开始,长度为len的字节输出到输出流中

Writer的write方法

方法 描述
void write(int c) 将指定的字符输出到输出流中,其中c代表字符
void write(char[] cbuf) 将字节字符数组中的数据输出到指定输出流中。
abstract void write(char[] cbuf, int off, int len) 将字符数组中从off位置开始,长度为len的字符输出到输出流中

Writer可以直接写字符串

因为字符流直接以字符作为操作单位,所以Writer可以用字符串来代替字符数组,即以String对象作为参数。Writer里还包含如下两个方法

方法 描述
void write(String str) Writes a string.
void write(String str, int off, int len) Writes a portion of a string.

OutputStream其他方法

方法 描述
void flush() Flushes this output stream and forces any buffered output bytes to be written out.
void close() Closes this output stream and releases any system resources associated with this stream.

Writer其他方法

方法 描述
abstract void flush() Flushes the stream.
abstract void close() Closes the stream, flushing it first.
Writer append(char c) Appends the specified character to this writer.
Writer append(CharSequence csq) Appends the specified character sequence to this writer.
Writer append(CharSequence csq, int start, int end) Appends a subsequence of the specified character sequence to this writer.

程序 通过字节流复制文件

下面程序使用FileInputStream来执行输入,并使用FileOutputStrean来执行输出,用以实现复制FileOutputStreamTest.java文件的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.io.*;

public class FileOutputStreamTest {
public static void main(String[] args) {
try (
// 创建字节 输入流
FileInputStream fis = new FileInputStream("FileOutputStreamTest.java");
// 创建字节 输出流
FileOutputStream fos = new FileOutputStream("newFile.txt")) {
byte[] bbuf = new byte[32];
int hasRead = 0;
// 循环从输入流中取出数据
while ((hasRead = fis.read(bbuf)) > 0) {
// 赌一次写一次,读了多少,就写多少。
fos.write(bbuf, 0, hasRead);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

运行上面程序,将看到系统当前路径下多了一个文件:newFile.txt,该文件的内容和FileOutputStreamTest.java文件的内容完全相同。

一定要关闭输出流

使用JavaIO流执行输出时,不要忘记关闭输出流,关闭输岀流除可以保证流的物理资源被回收之外,可能还可以将输岀流缓冲区中的数据flush到物理节点里(因为在执行close()方法之前,自动执行输出流的flush()方法)。
Java的很多输出流默认都提供了缓冲功能,其实没有必要刻意去记忆哪些流有缓冲功能、哪些流没有,只要正常关闭所有的输出流即可保证程序正常。

程序 使用Writer输出字符串

如果希望直接输出字符串内容,则使用Writer会有更好的效果,如下程序所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.*;

public class FileWriterTest {
public static void main(String[] args) {
try (FileWriter fw = new FileWriter("poem.txt")) {
fw.write("锦瑟 - 李商隐\r\n");
fw.write("锦瑟无端五十弦,一弦一柱思华年。\r\n");
fw.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃。\r\n");
fw.write("沧海月明珠有泪,蓝田日暖玉生烟。\r\n");
fw.write("此情可待成追忆,只是当时已惘然。\r\n");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

运行上面程序,将会在当前目录下输出一个poem.txt文件,文件内容就是程序中输出的内容。

不同平台的换行符

上面程序在输出字符串内容时,字符串内容的最后是\r\n,这是Windows平台的换行符,通讨这种方式就可以让输出内容换行;
如果是Unix/Linux/BSD等平台,则使用\n就作为换行符。