网络程序的很大一部分是简单的输入输出,即从一个系统向另一个系统移动字节。字节就是字节,在很大程度上,读服务器发送的数据与读取文件没什么不同;向客户传送数据与写入一个文件也没有什么区别。
Java中输入和输出组织不同于大多数其他语言。它是建立在流(stream)上。不同的基本流类(如java.io.FileInputStream和sun.net.TelnetOutputStream)用于读写特定的数据资源。但是所有的基本输出流使用同一种基本方法读数据。
过滤器流可以连接到输入流或输出流。它可以修改已经读出或写入的数据(例如,加密或压缩数据),或者可以简单地提供附加方法将已经读出或写入的数据转化成其他格式。
最后Reader和Writer也可以链接到输入流和输出流,从而允许程序读出和写入文本(即字符)而不是字节。如果使用正确,Reader和Writer能够处理多种类型的字符编码,包括SJIS和UTF-8等多字节字符集。
一、输出流
java的基本输出流是
java.io.OutputStream.
public abstract class OutputStream
public abstract void write(int b) throws IOExceptionn
public void write(byte[] data) throws IOException
public void write(byte[] data,int offset,int length)throws IOExceptionn
public void flush() throws IOException
public void close() throws IOExceptionOutputStream的子类使用这些方法向指定媒体写入数据。
我始终相信,我们理解了为什么它们存在,就会更好地记住它们,好,现在开始说一下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
public abstract int read() throws IOException
public int read(byte[] data) throws IOException
public int read(byte[] data,int offset,int length) throws IOException
public long skip(long n) throws IOException
public int available() throws IOException
public void close() throws IOExceptionInputStream
具体子类使用这些方法从指定媒体读取数据。但是不论读取何种资源,几乎只能使用这六种方法。有时你甚至可能不知道正在从哪种类型的流中读取数据。如隐藏在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;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类型的处理问题,大家可要注意阿,
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
bytesRead+=in.read(input,bytesRead,byteToRead-bytesRead);}
分享到:
相关推荐
JAVA中,字节流和字符流的套用,提供IO输入输出的基本语法和步骤
Java的输出输出流详解及输入输出实例 文件的基本操作
计算机编程语言概述 JAVA的一些基本概念还有变成规则
java输入与输出的基本流程图,对字节与字符的操作
设计一个仿记事本软件,实现新建、打开、保存、另存为等基本功能
详细介绍了Java 基本语法, Java类、对象、接口和包 , 异常处理 , Applet编程 , Java中的GUI ,Java中的线程 ,输入输出流,适合Java初学者学习,内容很详细
StudentCreate 基本信息录入=null; ModifySituation 基本信息修改=null; Inquest 基本信息查询=null; Delete 基本信息删除=null; JMenuBar bar;//菜单条 JMenu fileMenu;//菜单 JMenuItem 录入,修改,查询,...
–输出流:将程序中的数据输出到磁盘或保存到磁盘(将内存中的数据持久化到磁盘) ②,按照处理数据类型的单位不同:字节流和字符流 –字节流:以字节byte为单位 如:音频、视频、图像(一次读入或者读出8位二进制)...
第9章 输入输出流I/O基本原理22 October 2019输入输出流v为了实现对外设的统一管理,屏蔽不同外设的差异,Java用java.io包实现上层软件与
Java输入输出(IO)和流的基本概念_Java教程共2页.pdf.zip
输出流:程序到目的地(OutPutStream、Writer写出去) 处理数据单元: 字节流:按照字节读取数据(InputStream、OutputStream) 字符流:按照字符读取数据(Reader、Writer) 功能不同: 节点流:可以直接从数据源或...
javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流中产生的低级别 I/O。 javax.management 提供 Java Management Extensions 的核心类。 javax.management.loading 提供实现高级动态加载的类...
上学时候做的课设,虽然很简单,不过java基本的gui元素差不多都用上了……拿来混分了www
输入时压缩输入,输出时压缩输出,重载了inputstream和outputstream类,一个实现在输入时压缩,一个实现输出时解压,第一个类是成功的,第二个类还有问题。最好是根据jdk1.6的压缩类改造,可性我基本功不够。
它包含了常见的IO类和方法的使用示例,旨在帮助理解和掌握Java中的输入输出操作。 包含: File 类、RandomAccessFile 类、字节流(文件字节流、缓冲字节流、基本数据类型字节流、打印流、对象序列化流、字节数组流)...
代码虽然较短,但是包含界面开发、事件监听等知识,并且基本每行都有注释,适合刚开始接触java的同学们学习
7 Java流 用输入输出流实现从一个文本文件中读写简单数据。 8 泛型与容器 编程实现set、list与map的简单应用。 9 图形用户界面 用图形界面工具,结合事件处理机制,实现一个可视化的计算器。 10 JDBC基础 使用JDBC...
Java的常用方法说明 包括 输入输出流,java网络的基本知识,Java与图像,Java数据库连接(JDBC) ,Java与多媒体 ,Java Swing基础
1. 什么是流 ...Java中基本的两个字节流类是InputStream和OutputStream,它们分别代表了组基本的输入字节流和输出字节流。InputStream类与OutputStream类均为抽象类,我们在实际使用中通常使用Java类库中提
Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...