文章分类 | 推荐文章 | 最新文章 | 热点文章 | 最新软件 | 精品软件 | 下载排行 | 推荐下载 | 免费看大片 | WPS | 杀毒软件
清风网络
首 页 软件下载 网络学院 数码学院
QQ 电脑入门 游戏 操作系统 图形处理 办公软件 媒体动画 精文荟萃 工具软件 网络编程 程序开发 网络技术 认证考试 网站建设 文章专栏
当前位置:清风网络学院程序开发JavaJava 网络编程---I/O部分学习笔记整理1
精品推荐
特别推荐
·实例讲解:Java中的SOAP技术
·Java语言出现的背景 影响及前景
·Java精华积累:初学者都应该搞懂的问题
·Java多媒体框架设计自动播放机实例详解
·如何有效防止Java程序源码被人偷窥?
·Cell插件在J2EE系统中的应用
·初学者想学Hibernate,初级基础教程
·Java语言实现支持视频点播的WEB服务器
·关于Java编程的中文问题的几条分析原则
·确保J2ME无线移动商业应用程序的安全性
·Java开源技术:Eclipse的使用技巧详解
·新手入门:Java中的修饰词使用方法总结
·JAVA开发者应该去的20个英文网站
·使用JDBC创建数据库访问程序
·JDK的命令详解
·Java学习从入门到精通(附FAQ)
·Tomcat性能调整
·JSF:Java中面向Web开发的生旦净末丑
·对Java语言入门初学者的一些建议
·Java技术的新方向
热点TOP10
·Java图形用户界面设计
·在桌面应用中使用JAVA DB
·3D编程指南第一部分:快速进入移动JAVA 3D编程世界
·java swing的拖放例子
·用Java编写的记事本程序(1)
·用Java编写的记事本程序(3)
·JasperReport经验谈
·图解JBuilderX安装与实践
·用java编写的小游戏源代码分析
·struts+spring+ibatis轻量级J2EE开发
·单源点最短路径Dijkstra算法的JAVA实现
·实例讲解:Java中的SOAP技术
·初学者想学Hibernate,初级基础教程
·中国农历二百年算法及年历程序分析一
·用Java实现SMTP服务器
·Java语言出现的背景 影响及前景
·Java Applet 入门第三天
·用Java编写的记事本程序(2)
·Java学习从入门到精通(附FAQ)
·通过JCA实现企业级应用程序的“即插即用”

Java 网络编程---I/O部分学习笔记整理1

日期:2007年5月2日 作者: 查看:[大字体 中字体 小字体]


       网络程序的很大一部分是简单的输入输出,即从一个系统向另一个系统移动字节。字节就是字节,在很大程度上,读服务器发送的数据与读取文件没什么不同;向客户传送数据与写入一个文件也没有什么区别。

       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的具体子类使用这些方法从指定媒体读取数据。但是不论读取何种资源,几乎只能使用这六种方法。有时你甚至可能不知道正在从哪种类型的流中读取数据。如隐藏在sun.net包中TelnetInputStream是一个文档没有说明的类。TelnetInputStream的实例由java.net包中的多种方法返回;如java.net.URL的openStram()方法。但是,这些方法仅声明了返回InputStream,而不是更加明确的子类TelnetInputStream,这又是多态性在起作用了。子类的实例可以作为超类的实例透明使用。

来了,又来说明方法的由来了。

Ø         public abstract void read() throws IOException

InputStream类的基本方法是没有参量的read()方法(这个与OutputStream不同了)。该方法从输入流资源读取一个单个字节数据并将数据作为0到255之间的数返回,返回-1时表示流的结尾。因为Java没有无符号字节的数据类型,所以数据以整型类型返回。Read()方法等待和阻塞该方法后人和代码的执行,直到获得数据的一个字节并准备读取该字节。因此,输入和输出可能相当慢,这时用户如果需要完成其他比较重要的任务时,最好试图将I/O放到它们自己的线程中。Read()方法被声明为抽象方法,因为子类需要改变它来处理特定媒体。给个例子

byte[] input=new byte[10];

for(int i=0;i<input.length;i++){

       int b=in.read();

       if(b==-1) break;

       input[i]=(byte)b;

}

上面尽管read()方法仅读取字节,但是它返回的是整型值。因此在将结果存储到字节数组之前,需要一个类型转换的过程。当然,这会产生一个介于-128到127的有符号字节,而不是read()方法返回的0到255之间的一个无符号字节。但是,只要用户清楚使用的是无符号还是有符号字节就不会有很大问题。因此,我们可以把一个有符号字节转化成无符号字节(转换的原因是只有范围在0-255的整数才可以被存储在java的一个byte类型的变量中)。

int i=b>=0?b:256+b;

这里费了大篇幅,说明了read()返回的与java的byte类型的处理问题,大家可要注意阿,如果对java的原始数据类型还有兴趣,可以看一下我的原始数据类型学习笔记(未完成)。

 

Ø         public int read(byte[] data) throws IOException、public int read(byte[] data,int offset,int length) throws IOException

每次读取一个字节和每次写入一个字节效率都不高,因此read(byte[] data)和read(byte[] data,int offset,int length)也相应产生了。这两个方法将从流中读取的多个字节填充到一个指定的数组中。注意:这些填充到数组的操作不一定会成功的。一个很普遍的情况是一个读试图不会完全失败也不会完全成功,它可能读出请求数据的一部分字节,而不是全部字节。例如,当实际上只有512字节已经到达服务器时,用户可能会试图从一个网络流上读取1024字节,而其他字节仍然在传送中,这些字节最终会到达服务器,但到达时却已是不可以获得的。因此,多字节读取方法会返回实际读取的字节数目。给个例子

byte[] input=new byte[1024];

int bytesRead=in.read(input);

代码段试图从InputStream in读取1024字节到数组input中。但是,如果仅有512字节可以获得,则这些字节就是将要读取的全部字节,并且bytesRead值会设为512。但我们为了保证在实际上读取到所有的字节,怎么办?看

int bytesRead=0;

int byteToRead=1024;

byte[] input=new byte[byteToRead];

while(bytesRead<byteToRead){

       bytesRead+=in.read(input,bytesRead,byteToRead-bytesRead);

}

Ø         public int available() throws IOException

如果由于某种原因用户不希望读取数据,除非用户想要的全部数据可以立即得到,这时候就可以用available()方法返回的字节数是能够读取的最小字节数,而在实际上可以读取更多的字节,但是能够读取的字节数据至少与available()返回的字节数一样多。

看例子

int bytesAvailable=in.available();

byte[] input=new byte[bytesAvailable];

int byteTead=in.read(input,0,bytesAvailable);

//其他代码

这里我们可以断言bytesRead正好等于bytesAvailable,但不能断言bytesRead>0,因为available()返回0是有可能的。

流结束时:

available()返回0;

read(byte[] data,int offset,int length)通常返回-1;

       流没有结束,可读取字节数即available()得到的值为0时

read(byte[] data,int offset,int length)会忽略流的结束,返回0;

 

Ø         public long skip(long n) throws IOException

在极少数情况下,用户可能希望跳过数据而不去读取它们。Skip()方法就是实现这个功能的。这个方法在从文件读取数据时较为有用,而在网络连接流上则用处较小。因为网络连接流是有序的而且通常很慢,因此读取数据的耗时不会太多的超过跳过数据的耗时。文件可以随机访问,因此我们通过重定位文件指针就能简单的实现数据的跳转,而不是跳过每一个字节。

 

Ø         public void close() throws IOException

和输出流一样,程序利用完输入流之后,就应该调用close()方法关闭该输入流了(要记住啊)。该方法会释放与输入流有关的所有资源,如文件句柄和端口。一旦输入流关闭,再从它读取数据时会触发IOException。但是,有些类型的流可能仍允许对对象进行一定的操作。例如,用户通常不希望从java.security.DigestInputStream中获取报文摘要,除非已经读取了所有数据并且关闭了输入流。

 

看到这里或许你还会问怎么还有三个方法没有呢,对,还有三个不常用的方法

public void mark(int readAheadLimit)

public void reset() throws IOException

public boolean markSupported();

这些方法允许程序备份和重新读取已经读取过的数据。要实现这个功能,需要用mark()方法在输入流中的当前位置作个标记,在以后的某点可以使用reset()方法重新将流定位到标记处,随后的读取将返回从标记初开始的数据。但是,从标记处到重新将流定位点不能任意长。重新定位到标记处之前允许读取的字节数就是由mark()的变量readAheadLimit决定。多长就会触发IOException,而且任何指定时刻,输入流中只可以有一个标记,如果标记了第二个标记,就会覆盖第一个标记了。其实标记和重新设置位置都是通过存储从内部缓冲区中的标记位置读出每一字节来实现。最麻烦的状况是,并非所有输入流都支持标记和重新设置位置的。所以在设置之前要用markSupported()方法检测一下。

实际上不支持标记和重新设置位置的流多于支持它们的流。Elliotte Rusty Harold大师觉得这几个方法设计的标准不高,将功能性与一个许多甚至可能是大部分子类都不可用的抽象超类结合是一个相当拙劣的想法。最好是将这三个方法放在不同的接口中。提供类似于markSupported()方法在运行时进行功能性检测是较为传统,非面向对象的解决方法。面向对象的方法将通过接口和类把该方法嵌入到面向对象系统中,从而在编译时检测所有的流。

Java.io中总是支持标记的输入流:BufferedInputStream和ByteArrayInputStream。

[1] [2] 下一页 




上一篇:一篇不错的介绍Java Socket编程的文章

下一篇:java中Properties类的使用

Java 网络编程---I/O部分学习笔记整理1 相关文章:
·教你学习如何破解XP登陆密码
·直面笔记本电脑购买中的猫腻
·《边看边打赚大奖--迅雷宽频》部分问题及答案
·网络玄幻小说十大网站
·国内大学校园网网络建设方案参考
·屏蔽五项网络功能 让XP系统极速狂飙
·AIX 5L 学习大纲/简易教程(2)(未经许可,请勿COPY)
·socket编程原理
·笔记本电脑无线上网解决方案大比拼
·中小企业整体网络安全解决方案解析
Java 网络编程---I/O部分学习笔记整理1 相关软件:
·网络常见问题与故障1000例
·洪恩轻松教你学电脑_internet学习
·网络神偷10.4 版
·盈速通网络加速器V1.2
·鸟哥的linux私房菜:基础学习篇
·高级计算机网络
·红太阳网络电视v17.3
·新东方演讲录 俞敏洪老师学习英语与人生奋斗
·UUSee网络电视 2007V4.4.801.53
·2007网络安全黄皮书V1.0.0

特别声明:本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
[打印本页] [关闭窗口] 转载请注明来源:http://www.viphot.com
| 帮助(?) | 版权声明 | 友情连接 | 关于我们 | 信息发布
Copyright 2007 www.viphot.com All Rights Reserved. 鄂ICP备05000083号Powered by:viphot