A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© tfy 中级黑马   /  2012-12-27 00:06  /  1507 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1. 网络程序的很大一部分是简单的输入输出,即从一个系统向另一个系统移动字节。字节就是字节,在很大程度上,读服务器发送的数据与读取文件没什么不同;向客户传送数据与写入一个文件也没有什么区别。
       Java中输入和输出组织不同于大多数其他语言。它是建立在流(stream)上。不同的基本流类(如java.io.FileInputStream和sun.net.TelnetOutputStream)用于读写特定的数据资源。但是所有的基本输出流使用同一种基本方法读数据。
       过滤器流可以连接到输入流或输出流。它可以修改已经读出或写人的数据(例如,加密或压缩数据),或者可以简单地提供附加方法将已经读出或写入的数据转化成其他格式。
       最后Reader和Writer也可以程序读出和写入文本(即字符)而不是字节。如果使用正确,Reader和Writer能够处理多种类型的字符编码,包括SJIS和UTF-8等多字节字符集。

一、输出流

java的基本输出流是 java.io.OutputStream.
public abstract class OutputStream

n         public abstract void write(int b) throws IOException
n         public void write(byte data) throws IOException
n         public void write(byte data,int offset,int length) throws IOException
n         public void flush() throws IOException
n         public void close() throws IOException
OutputStream的子类使用这些方法向指定媒体写入数据。

我始终相信,我们理解了为什么它们存在,就会更好地记住它们,好,现在开始说一下OutputStream类的方法的由来
Ø         public abstract void write(int b) throws IOException

OutputStream的基本方法是write(int b)。该方法将介于0到255之间的整数看作变量,并将相应的字节写到一个输出流。该方法声明是个抽象方法,因为子类需要改变它以处理特定媒体。例如,ByteArrayOutputStream可以使用拷贝字节到其数组的纯Java代码来实现方法。但是,FileOutputStream就需要使用代码,此代码应该理解如何在主机平台上将数据写入文件。注意:尽管该方法把整形值作为变量,但是它实际上写入的是一个无符号字节。Java没有无符号字节数据类型,因此这里使用整型来代替。无符号字节和有符号字节之间的真正区别是编译器对它们的解释。二者都是由8位组成,并且当使用write(int b)将一个int写入到网络连接流时,只有8位数据传送。如果将一个超出0-255范围的int传给write(int b),则写入该数字的低位字节,而忽略余下的三个字节(大家都知道java的int是4个字节的,这里本质就是将int转换为byte)。

Ø         public void write(byte data) throws IOException和public void write(byte data,int offset,int length) throws IOException

每次写入一个字节通常效率不高。因此,大部分TCP/IP程序将数据存入一定长度的缓冲区,即在内存中累积字节,并仅当累积了一定数目字节或过了一定的时间段,才将它们发送到最终的目的地。因此write(byte data)和write(byte data,int offset,int length)就是这样产生了。

Ø         public void flush() throws IOException

我们可以在软件中或直接在Java代码中对流实施缓冲操作,也可以在网络硬件中对流实施缓冲操作。就好像BufferedOutputStream或BufferedWriter链接到底层流来实现流缓冲。因此,如果正在写入数据,则刷新输出流是相当重要的。例如,假设已经写入了一个300字节的请求给一个HTTP Keep-Alive的HTTP服务器,通常希望在发送更多数据之间等待响应。但是,如果输出流有一个1024字节的缓冲区,则该流可能在将数据发送出缓冲区之前正在等待更多的数据到达,但是这些数据似乎不会到达的,因为它们还没有发送出去,但是缓冲流不会发送数据给服务器,除非它从底层流获得更多的数据,但是底层流不会发送更多的数据,除非它从服务器获得数据,而服务器不会发送数据,除非它获得保留在缓冲区中的数据(死锁了!),flush()方法就可以解决了这个僵局,因为即使缓冲区未满,他也会强制要求实行缓冲操作的流传送数据。注意:是否对流实行了缓冲操作,这决定于你如何获得指向流的引用(例如,不论是否希望对System.out执行缓冲操作,都会对其实施缓冲)。如果刷新流需要刷新时,就必须刷新,但是如果刷新失败了就会导致不可预料、不可重复的程序挂起(flush()返回值是void啊),如果事先不了解挂起问题所在,就很难解决这个问题了。因此,在关闭所有流之前,应当立即刷新它们。否则,关闭流前,缓冲区中的剩余数据可能会丢失。

Ø         public void close() throws IOException

最后当利用完流之后,应当调用close()方法关闭流。它会释放所有与这个流相关的资源,如文件句柄或端口。一旦输出流关闭了,再向其写入数据就会触发IOException异常。但是,有些类型可能允许对对象进行一定操作。如一个已关闭的ByteArrayOutputStream仍然可以转化成一个实际的字节数组,而且一个已关闭的DigestOutputStream仍可以返回其摘要。

二、输入流

java的基本输入流是java.io.InputStream
public abstract class InputStream
n         public abstract int read() throws IOException
n         public int read(byte data) throws IOException
n         public int read(byte data,int offset,int length) throws IOException
n         public long skip(long n) throws IOException
n         public int available() throws IOException
n         public void close() throws IOException
InputStream的具体子类使用这些方法从指定媒体读取数据。但是不论读取何种资源,几乎只能使用这六种方法。有时你甚至可能不知道正在从哪种类型的流中读取数据。如隐藏在



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马