admin 管理员组

文章数量: 887021


2024年1月10日发(作者:吕氏春秋写的什么内容)

输入输出流是一个常把人搞晕的概念,问题出在哪儿?问题出在我们犯了习惯性思维的毛病,落入了“输入”、“输出”两词制造的陷井。

一讲到输入流,我们常常会不言而喻地把它理解为这个对象是用来读其他对象的,如把字节数组、字符串等读进来;同样,一说到输出流,常常会把它理解为,这个对象就是用来输出的,如把字节数组、字符串的内容输出来或写出来,等等。要是这样理解,整好把它们理解错了个180度。实际上我们首先应当把输入流和输出流分别这样理解:输入流的核心机能是把属于“自已缓冲区的”内容一个符一个符地读出来(可称为吐出来),展现给你;输出流的核心机能是把其它对象的内容一个符一个符地“写到属于自已的内存缓冲区”里去(可称为吃进去)。下面我们来具体看一看:

(一)ByteArrayInputStream(字节数组输入流)

从字面上看ByteArrayInputStream是输入流,其实,我们对它的应用主要是把存放在它内部的东东(或者说把与它有联系的字节数组)一个一个字节地或成组地读(read)出来。当我们想对一个字节数组一个字节一个字节进行过滤的时候,可以用它来实现。

使用这个类通常用以下几个步骤与方法

(1)创建实例(也有的叫创建对象)。如:

byte buffer[]={'T','e','s','t'};//可以用其他方法制作数组。

ByteArrayInputStream inStream=new ByteArrayInputStream(buffer);

(当然还有另外的构造方法)

inStream即为实例。这一步的作用,我们可以把它理解为inStream把buffer数组一次性地复制到自已内部的缓冲区,以后,inStream内部的各方法如read、skip、available、reset的操作对象就是这个内部缓冲区。也就是说,我们可以认为,imStream内部有一个private(私有的)缓冲区,这个缓冲区被封装在inStream内,只有inStream的方法可以对它操作,外界是不可以直接读写这个缓冲区的。构造inStream的过程,就是复制外部字节数组到inStream 私有缓冲区建立inStream的过程。

(2)让inStream来完成我们所要完成的任务。

你要让inStream来完成你想要完成的任务,必须是inStream所能完成的,也就是说,inStream必须要有相应的方法。inStream有哪些方法呢,有以下一些:

public synchronized int read() 就是把实例缓冲区的内容一个字节一个字节地读出来,这是这个类最有价值的方法

public synchronized int read(byte b[],int offset,int length) 读出多个字节(到b数组),返回值一般为读到的字节数。但读到末尾时返回-1。

Public synchronized long skip(long n) 调用这个方法我们可以跳过我们想要跳过去的n个字节,当然,跳过的字节数必须是符合实际的(返回的就是跳过的字节数)

public synchronized int available 调用这个方法我们可以得到私有缓冲区的字节数

public synchronized void reset() 调用这个方法我们可以把私有缓冲区的指针调回到起始处,以便我们可以再重新来一次

等等。

这些方法的详细描述和具体使用我就不赘述了,要了解详情请查阅有关资料。

(二)ByteArrayOutputStream(字节数组输出流)

从字表看,ByteArrayOutputStream是输出流,问题是输出谁,输出到哪儿?哪儿是源,哪儿是目的地?其实我认为这个类也有它自已的private缓冲区(下称私有缓冲区),与ByteArrayInputStream不同的是,这个缓冲区是专门用来从外界吃字符进来的缓冲区,这个吃进来的动作是由该类的write方法来实现的。

使用这个类通常用以下几个步骤与方法:

(1)创建实例。

创建实例的方法是:

ByteArrayOutputStream outStream = new ByteArrayOutputStream();

或者是如:

long num=1024*1024;

ByteArrayOutputStream outStream = new ByteArrayOutputStream(num);

第二种方法创建了一个输出流实例,其中这个输出流的私有缓冲区长为1024*1024。很明显,第 1 页 共 3 页

这个缓冲区一开始是空白的,它的作用就是为写信息进来准备空间。

(2)让outStream完成你想要完成的任务

与ByteArrayInputStream一样,ByteArrayOutputStream类也有属于自己的方法,主要有:

public sysnchronized void write(int b) 写一个字节(b)进来

public sysnchronized void write(byte b[],int offset,int length) 把b中的一部分字节写进来

Public sysnchronized void writeTo(OutputStream out) 把缓冲区内容写到另一输出流out

public sysnchronized void reset() 把私有缓冲区指针重调到缓冲区开始处

public syschronized byte[] toByteArray() 将私有缓冲区的内容作为一个字节数组返回(输出到一个数组中去)

public int size() 返回当前私有缓冲区大小

public String toString() 把私有缓冲区的内容转化为一个字符串

public String toString(hit hibyte) 把私有缓冲区的内容转化为一个字符串。其中hibyte指把字符(通常是8位的ASCII字符)转为16位的Unicode值时,高八位的值。

有关细节请查阅有关资料。

(三)小结 输入、输出流是Java系统的一个重要组成部分,我们必须准确地理解它,否则我们就不能正确的应用它。理解输入、输出流的基本线索是:输入流:首先是复制其他字节数组一次性填写自已的私有缓冲区,然后可以把私有缓冲区的内容一个一个地读出来,或成组地读出来,私有缓冲区的内容创建后只能读不能写。输出流:首先是创建一个空白的私有缓冲区,然后把外界的信息一个一个或成组地写进私有缓冲区,私有缓冲区可以多次写,其内容也可以一次性地转换成其他串、字节数组等,但不能一个一个地从私有缓冲区读出来(全部方法我没有查阅,先这么认为)。

输入流是为你提供原料的,而输出流是供你存放制作好的产品的(当然这是相对而言)。

上述的认知主要是针对ByteArrayInputStream和ByteArrayOutputStream的,是我的个人理解,不要死扣上面的字眼,更不要轻易地推广到一般。但尽管如此,理解了我上述所讲的两个流的“读出自己”与“写进自己”的实质,我认为对理解其它流也是有帮助的。

在学习认知其它的流时要注意,输入流可以通过复制(更准确地说是链接)其他输入流来创建实例,同样输出流也可以通过链接其他输出流来创建实例,这些内容留给网友们去思考与发挥吧。最后,让我把clone来的一个程序炒卖给大家,以结束我的胡言乱语。

//filename:

import .*;

public class ByteArrayIODemo

{

public static void main(String args[]) throws IOException

{

String s ="This a test";

byte buffer[]=es();

ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();

for(int I=0;I<;++I)

(buffer[I]);

//由字节数组创建字节输入流

ByteArrayInputStream inStream = new ByteArrayInputStream(Array());

//读写

boolean eof=false;

while(!eof)

{

int c=();

if(c==-1) eof=true;

else ((char)c);

}

n("nThe'writeTo' method can produce same results.");

//用ByteArrayOutputStream的writeTo()方法写

o();

();

//available()与reset()的使用

n("nThe buf of inStream has the length(before seset):"+ble());

第 2 页 共 3 页

();

n("nThe buf of inStream has the length:"+ble());

();

}

}

第 3 页 共 3 页


本文标签: 缓冲区 字节 输出 数组 输入