1. 输出流
定义了基本的方法,包括写入数据,关闭和刷新流。
public abstract void write(int b) throws IOException public void write(byte[] data) throws IOException public void write(byte[] data, int offset, int length) throws IOException public void flush( ) throws IOException public void close( ) throws IOException
OutputStream只是抽象类,子类提供了write(int b)方法的实现。
例如FileOutputStream使用本地方法覆盖了这五个方法。
通过getOutputSteam能够获取输出流,但通常就只会返回OutputStream,具体细节将会被屏蔽
public OutputStream getOutputStream( ) throws IOException但有时由于实现的需要,也会返回OutputStream的子类。
此外,即使你不知道返回的子类是什么,或者子类是否覆盖了该方法,你也可以使用继承自OutputStream的这几个方法。
2.向流中写入字节
基本的写入方法如下:
public abstract void write(int b) throws IOException写入无符号的0~255,超出的都将以余256的方式使其落入指定范围之中。
3. 向流中写入字节数组
一次写入一块要比一个一个字节写入要快,这是通用的方法:
public void write(byte[] data) throws IOException public void write(byte[] data, int offset, int length) throws IOException
第二个写入方法包含了偏移地址和长度。
反过来,如果一次写入的内容过多,也会导致性能问题。
实际中,取决于数据写入的目的地。
对于文件而言,最佳实践是文件块的少量数倍,典型的数值是1024,2048或者4096个字节,
网络连接则使用更小的块,如128或者256。
4. 关闭输出流
当你完成流的输出时,你应该关闭它。
关闭操作将释放与流结合的资源。
方法签名如下:
public void close( ) throws IOException这个操作将释放资源,例如文件句柄或者网络端口之类的。
一旦你关闭了流,你将不可再写入。
但是,也不是所有的流都需要关闭,但与文件和网络相关的则必须关闭。否则,会导致你持有的文件或者网络资源无法被其他进程所使用,从而阻塞进程。
通常一个文件是这样关闭的。
try {
OutputStream out = new FileOutputStream("numbers.dat");
// Write to the stream...
out.close( );
}
catch (IOException ex) {
System.err.println(ex);
}
然而,这个代码片段有潜在的泄露可能。你应该把close放在 finally block中:
OutputStream out = null; try { out = new FileOutputStream("numbers.dat"); // Write to the stream... } catch (IOException ex) { System.err.println(ex); } finally { if (out != null) { try { out.close( ); } catch (IOException ex) { System.err.println(ex); } } }
这种内嵌try-catch看起来很丑,所以,你也可以考虑将异常抛出,而不是catch它
OutputStream out == null;
try {
out = new FileOutputStream("numbers.dat");
// Write to the stream...
}
finally {
if (out != null) out.close( );
}
5. 可关闭接口
Java5增加了可关闭接口,OutputStream实现了它。
package java.io; public interface Closeable { void close( ) throws IOException; }
6. 刷新流
public void flush( ) throws IOException通常你无须执行刷新流的操作,而让其在close时进行刷新即可。
但是,如果整个过程时间很长的话,还是有必要周期的进行刷新操作。
在debug崩溃程序时,刷新操作也很有用。
OutputStream实现接口Flushable
7. 子类化OutputStream
子类必须实现抽象的write(int b)方法。
下面是一个简单的OutputStream的子类,它的write什么也没干。
package com.elharo.io;
import java.io.*;
public class NullOutputStream extends OutputStream {
private boolean closed = false;
public void write(int b) throws IOException {
if (closed) throw new IOException("Write to closed stream");
}
public void write(byte[] data, int offset, int length)
throws IOException {
if (data == null) throw new NullPointerException("data is null");
if (closed) throw new IOException("Write to closed stream");
}
public void close( ) {
closed = true;
}
}
[注意]默认的close和flush都是空实现。