Java流-IO

参考Java网络编程

Java的I/O建立在流(stream)之上。

过滤器(filter)流可以串链到输入流或输出流上。在读写时,过滤器可以修改数据(如加密或压缩),或者只是提供额外的方法将数据转为其他的格式。

reader、writer允许程序读写的文本而不是字节。

过滤器

过滤器有两个版本:过滤器流以及阅读器和书写器。过滤器任然主要讲原始数据作为字节处理,例如通过压缩数据或结束为二进制数字。reader、writer处理多种编码文件的特殊情况,如UTF-8和ISO 8859-1。

过滤纯粹是内部操作,不提供任何新的公共接口。

FileInputStream fin = new FileInputStream("data.txt");
BufferedInputStream bin = new BufferedInputStream(fin);

过滤器通过其构造函数与流连接。如上。这种连接是永久的,过滤器无法与流断开连接。

缓冲流

BufferedOutputStream类将写入的数据存储在缓冲区中,知道缓冲区满或刷新输出流。然后她将数据一次性全部写入底层输出流。

一次写入多字节和多次写入少量字节相比,前者往往要快得多。对于网络连接尤其是这样,因为每个TCP片或UDP包都有一定数量的开销,一般大约为40字节。这意味着,如果一次执法1字节,那么发送1K数据实际上需要通过线缆发送40K,而一次全部发送只需发送1K多一点点数据。大多数网卡和TCP实现自身都提供一定程度的缓冲,所以实际的数量不会那么夸张。尽管如此,缓冲网络输出通常会带来巨大的性能提升。

BufferedInputStream和BufferedOutputStream都有两个构造函数

public BufferedInputStream(InputStream in)
public BufferedInputStream(InputStream in, int bufferSize)
public BufferedOutputStream(OutputStream in)
public BufferedOutputStream(OutputStream in, int bufferSize)

第二个参数会指定缓冲区中的字节数。输入默认为2048字节,输出为512字节。

BufferedInputStream没有声明自己额任何新办法。他只覆盖,支持标记和重置。两个多字节read()方法尝试根据需要多次从底层输入流中读取数据,从而完全填充指定的数组或子数组。只有数组或子数组完全填满、到达流的末尾或底层流阻塞而无法进一步读取时,这两个read()才返回。大多数输入流都不这么做,他们在返回前只从底层流或数据源中读取一次。

BufferedOutputStream每次邪恶如会吧数据放在缓冲区中,而不是直接放入底层的输出流。因此需要发送数据时应当刷新输出流,这一点非常重要。

PrintStream

默认情况下,打印流应当显示刷新输出。不过,如果autoFlush参数为true,那么每次写入1字节数组或换行,或者调用println()方法时,都会刷新输出流。

PrintStream有九个重载的print()方法和10个重载的println()方法。每个print()方法都将器参数以可预见的方式转换为一个字符串,再用默认的编码方式把字符串写入底层输出流。println方法会在所写行末尾追加与平台有关的行分隔符。在UNIX是(\n),Mac OS 9下是(\r),Windows下是(\r\n)。


警告:网络程序员应当慎用PrintStream


问题一:println的输出与平台有关。大多数网络协议(如HTTP和Gnutela)明确指定行应当以回车/换行对结束。

问题二:PrintStream假定使用所在平台的默认编码方式。不过这种编码方式可能不是服务器或客户端所期望的。

问题三:PrintSteam吞掉了所有的异常。

数据流

DataInputStream和DataOutputStream可以用二进制格式读写Java的基本数据类型和字符串。所有数据都已big-endian(高位优先)格式写入。byte会写为1字节,short写为两个字节,int写为4个字节,long写为8个字节。浮点数和双精度数分别写为4字节和8字节的IEEE 754格式。布尔数写为1字节,0表示false。字符写为两个无符号字节。

writeChars针对String参数迭代处理,将各个字符顺序写为一个2字节的big-endian Unicode字符。writeBytes迭代处理String参数,但只写入每个字符的低字节。因此,如果字符串包含了Latin-1字符集以外的字符,其中的信息将会丢失。

writeChars和writeBytes不会对输出流中的字符串长度进行编码。writeUTF方法则包括了字符串的长度。她将字符串本身用Unicode UTF-8编码的一个变体进行编码。

DataInputStream的readFully方法会重复地从底层输入流向一个数组读取数据,直到读取了所请求的字节数为止。

Reader和Writer

对应于输入和输出流类层次体系,Java提供了一个基本上完整的镜像,用来处理字符而不是字节。

java.io.Reader类指定读取字符的API,java.io.Writer指定写字符的API。对应输入和输出流使用字节的地方,reader和writer会使用Unicode字符。过滤器Reader和Writer可以附加在其他Reader和Writer上,已提供额外服务或接口。

OutputStreamWriter是Writer的重要具体子类。它根据指定的编码方式将从Java程序中接受的字符转为字节,并写入底层输出流。如果没有指定编码方式,则使用平台默认的编码方式。

InputStreamReader 和 OutputStreamWriter 就相当于输入和输出流之上的装饰器,把面向字节的接口改为面向字符的接口。完成之后就可以将其他面向字符的过滤器放在使用java.io.FIlterReader 和 java.io.FilterWriter 类的阅读器或书写器上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值