Java中的BufferedInputStream与BufferedOutputStream使用示例
BufferedInputStream
BufferedInputStream是缓冲输入流。它继承于FilterInputStream。
BufferedInputStream的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。
BufferedInputStream本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。
BufferedInputStream函数列表:
BufferedInputStream(InputStreamin) BufferedInputStream(InputStreamin,intsize) synchronizedintavailable() voidclose() synchronizedvoidmark(intreadlimit) booleanmarkSupported() synchronizedintread() synchronizedintread(byte[]buffer,intoffset,intbyteCount) synchronizedvoidreset() synchronizedlongskip(longbyteCount)
示例代码:
关于BufferedInputStream中API的详细用法,参考示例代码(BufferedInputStreamTest.java):
importjava.io.BufferedInputStream;
importjava.io.ByteArrayInputStream;
importjava.io.File;
importjava.io.InputStream;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.FileNotFoundException;
importjava.lang.SecurityException;
/**
*BufferedInputStream测试程序
*
*@authorskywang
*/
publicclassBufferedInputStreamTest{
privatestaticfinalintLEN=5;
publicstaticvoidmain(String[]args){
testBufferedInputStream();
}
/**
*BufferedInputStream的API测试函数
*/
privatestaticvoidtestBufferedInputStream(){
//创建BufferedInputStream字节流,内容是ArrayLetters数组
try{
Filefile=newFile("bufferedinputstream.txt");
InputStreamin=
newBufferedInputStream(
newFileInputStream(file),512);
//从字节流中读取5个字节。“abcde”,a对应0x61,b对应0x62,依次类推...
for(inti=0;i<LEN;i++){
//若能继续读取下一个字节,则读取下一个字节
if(in.available()>=0){
//读取“字节流的下一个字节”
inttmp=in.read();
System.out.printf("%d:0x%s\n",i,Integer.toHexString(tmp));
}
}
//若“该字节流”不支持标记功能,则直接退出
if(!in.markSupported()){
System.out.println("makenotsupported!");
return;
}
//标记“当前索引位置”,即标记第6个位置的元素--“f”
//1024对应marklimit
in.mark(1024);
//跳过22个字节。
in.skip(22);
//读取5个字节
byte[]buf=newbyte[LEN];
in.read(buf,0,LEN);
//将buf转换为String字符串。
Stringstr1=newString(buf);
System.out.printf("str1=%s\n",str1);
//重置“输入流的索引”为mark()所标记的位置,即重置到“f”处。
in.reset();
//从“重置后的字节流”中读取5个字节到buf中。即读取“fghij”
in.read(buf,0,LEN);
//将buf转换为String字符串。
Stringstr2=newString(buf);
System.out.printf("str2=%s\n",str2);
in.close();
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
程序中读取的bufferedinputstream.txt的内容如下:
abcdefghijklmnopqrstuvwxyz 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ
运行结果:
0:0x61 1:0x62 2:0x63 3:0x64 4:0x65 str1=01234 str2=fghij
BufferedOutputStream
BufferedOutputStream是缓冲输出流。它继承于FilterOutputStream。
BufferedOutputStream的作用是为另一个输出流提供“缓冲功能”。
BufferedOutputStream函数列表:
BufferedOutputStream(OutputStreamout) BufferedOutputStream(OutputStreamout,intsize) synchronizedvoidclose() synchronizedvoidflush() synchronizedvoidwrite(byte[]buffer,intoffset,intlength) synchronizedvoidwrite(intoneByte)
示例代码:
关于BufferedOutputStream中API的详细用法,参考示例代码(BufferedOutputStreamTest.java):
importjava.io.BufferedOutputStream;
importjava.io.File;
importjava.io.OutputStream;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.FileNotFoundException;
importjava.lang.SecurityException;
importjava.util.Scanner;
/**
*BufferedOutputStream测试程序
*
*@authorskywang
*/
publicclassBufferedOutputStreamTest{
privatestaticfinalintLEN=5;
//对应英文字母“abcddefghijklmnopqrsttuvwxyz”
privatestaticfinalbyte[]ArrayLetters={
0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
};
publicstaticvoidmain(String[]args){
testBufferedOutputStream();
}
/**
*BufferedOutputStream的API测试函数
*/
privatestaticvoidtestBufferedOutputStream(){
//创建“文件输出流”对应的BufferedOutputStream
//它对应缓冲区的大小是16,即缓冲区的数据>=16时,会自动将缓冲区的内容写入到输出流。
try{
Filefile=newFile("out.txt");
OutputStreamout=
newBufferedOutputStream(
newFileOutputStream(file),16);
//将ArrayLetters数组的前10个字节写入到输出流中
out.write(ArrayLetters,0,10);
//将“换行符\n”写入到输出流中
out.write('\n');
//TODO!
//out.flush();
readUserInput();
out.close();
}catch(FileNotFoundExceptione){
e.printStackTrace();
}catch(SecurityExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
/**
*读取用户输入
*/
privatestaticvoidreadUserInput(){
System.out.println("pleaseinputatext:");
Scannerreader=newScanner(System.in);
//等待一个输入
Stringstr=reader.next();
System.out.printf("theinputis:%s\n",str);
}
}
运行结果:
生成文件“out.txt”,文件的内容是“abcdefghij”。
分步测试:分别按照下面3种步骤测试程序,来查看缓冲区大小以及flush()的作用。
第1种:原始程序
(1)运行程序。在程序等待用户输入时,查看“out.txt”的文本内容;发现:内容为空。
(2)运行程序。在用户输入之后,查看“out.txt”的文本内容;发现:内容为“abcdefghij”。
从中,我们发现(01)和(02)的结果不同;之所以(01)中的out.txt内容为空,是因为out.txt对应的缓冲区大小是16字节,而我们只写入了11个字节,所以,它不会执行清空缓冲操作(即,将缓冲数据写入到输出流中)。
而(02)对应out.txt的内容是“abcdefghij”,是因为执行了out.close(),它会关闭输出流;在关闭输出流之前,会将缓冲区的数据写入到输出流中。
注意:重新测试时,要先删除out.txt。
第2种:在readUserInput()前添加如下语句
out.flush();
这句话的作用,是将“缓冲区的内容”写入到输出流中。
(1)运行程序。在程序等待用户输入时,查看“out.txt”的文本内容;发现:内容为“abcdefghij”。
(2)运行程序。在用户输入之后,查看“out.txt”的文本内容;发现:内容为“abcdefghij”。
从中,我们发现(01)和(02)结果一样,对应out.txt的内容都是“abcdefghij”。这是因为执行了flush()操作,它的作用是将缓冲区的数据写入到输出流中。
注意:重新测试时,要先删除out.txt!
第3种:在第1种的基础上,将
out.write(ArrayLetters,0,10);
修改为
out.write(ArrayLetters,0,20);
(1)运行程序。在程序等待用户输入时,查看“out.txt”的文本内容;发现:内容为“abcdefghijklmnopqrst”(不含回车)。
(02)运行程序。在用户输入之后,查看“out.txt”的文本内容;发现:内容为“abcdefghijklmnopqrst”(含回车)。
从中,我们发现(01)运行结果是“abcdefghijklmnopqrst”(不含回车)。这是因为,缓冲区的大小是16,而我们通过out.write(ArrayLetters,0,20)写入了20个字节,超过了缓冲区的大小;这时,会直接将全部的输入都写入都输出流中,而不经过缓冲区。
(3)运行结果是“abcdefghijklmnopqrst”(含回车),这是因为执行out.close()时,将回车符号'\n'写入了输出流中。
注意:重新测试时,要先删除out.txt!