Java中的BufferedInputStream与BufferedOutputStream使用示例

作者:kuiwu-wang 时间:2021-10-20 01:14:56 

BufferedInputStream 
BufferedInputStream 是缓冲输入流。它继承于FilterInputStream。
BufferedInputStream 的作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”。
BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。
BufferedInputStream 函数列表:


BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size)

synchronized int   available()
void   close()
synchronized void   mark(int readlimit)
boolean   markSupported()
synchronized int   read()
synchronized int   read(byte[] buffer, int offset, int byteCount)
synchronized void   reset()
synchronized long   skip(long byteCount)

示例代码:
关于BufferedInputStream中API的详细用法,参考示例代码(BufferedInputStreamTest.java):


import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.lang.SecurityException;

/**
* BufferedInputStream 测试程序
*
* @author skywang
*/
public class BufferedInputStreamTest {

private static final int LEN = 5;

public static void main(String[] args) {
   testBufferedInputStream() ;
 }

/**
  * BufferedInputStream的API测试函数
  */
 private static void testBufferedInputStream() {

// 创建BufferedInputStream字节流,内容是ArrayLetters数组
   try {
     File file = new File("bufferedinputstream.txt");
     InputStream in =
        new BufferedInputStream(
          new FileInputStream(file), 512);

// 从字节流中读取5个字节。“abcde”,a对应0x61,b对应0x62,依次类推...
     for (int i=0; i<LEN; i++) {
       // 若能继续读取下一个字节,则读取下一个字节
       if (in.available() >= 0) {
         // 读取“字节流的下一个字节”
         int tmp = in.read();
         System.out.printf("%d : 0x%s\n", i, Integer.toHexString(tmp));
       }
     }

// 若“该字节流”不支持标记功能,则直接退出
     if (!in.markSupported()) {
       System.out.println("make not supported!");
       return ;
     }

// 标记“当前索引位置”,即标记第6个位置的元素--“f”
     // 1024对应marklimit
     in.mark(1024);

// 跳过22个字节。
     in.skip(22);

// 读取5个字节
     byte[] buf = new byte[LEN];
     in.read(buf, 0, LEN);
     // 将buf转换为String字符串。
     String str1 = new String(buf);
     System.out.printf("str1=%s\n", str1);

// 重置“输入流的索引”为mark()所标记的位置,即重置到“f”处。
     in.reset();
     // 从“重置后的字节流”中读取5个字节到buf中。即读取“fghij”
     in.read(buf, 0, LEN);
     // 将buf转换为String字符串。
     String str2 = new String(buf);
     System.out.printf("str2=%s\n", str2);

in.close();
   } catch (FileNotFoundException e) {
     e.printStackTrace();
   } catch (SecurityException e) {
     e.printStackTrace();
   } catch (IOException e) {
     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(OutputStream out)
BufferedOutputStream(OutputStream out, int size)

synchronized void   close()
synchronized void   flush()
synchronized void   write(byte[] buffer, int offset, int length)
synchronized void   write(int oneByte)

示例代码:
关于BufferedOutputStream中API的详细用法,参考示例代码(BufferedOutputStreamTest.java):


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.lang.SecurityException;
import java.util.Scanner;

/**
* BufferedOutputStream 测试程序
*
* @author skywang
*/
public class BufferedOutputStreamTest {

private static final int LEN = 5;
 // 对应英文字母“abcddefghijklmnopqrsttuvwxyz”
 private static final byte[] 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
 };

public static void main(String[] args) {
   testBufferedOutputStream() ;
 }

/**
  * BufferedOutputStream的API测试函数
  */
 private static void testBufferedOutputStream() {

// 创建“文件输出流”对应的BufferedOutputStream
   // 它对应缓冲区的大小是16,即缓冲区的数据>=16时,会自动将缓冲区的内容写入到输出流。
   try {
     File file = new File("out.txt");
     OutputStream out =
        new BufferedOutputStream(
          new FileOutputStream(file), 16);

// 将ArrayLetters数组的前10个字节写入到输出流中
     out.write(ArrayLetters, 0, 10);
     // 将“换行符\n”写入到输出流中
     out.write('\n');

// TODO!
     //out.flush();

readUserInput() ;

out.close();
   } catch (FileNotFoundException e) {
     e.printStackTrace();
   } catch (SecurityException e) {
     e.printStackTrace();
   } catch (IOException e) {
     e.printStackTrace();
   }
 }

/**
  * 读取用户输入
  */
 private static void readUserInput() {
   System.out.println("please input a text:");
   Scanner reader=new Scanner(System.in);
   // 等待一个输入
   String str = reader.next();
   System.out.printf("the input is : %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!

标签:Java,IO
0
投稿

猜你喜欢

  • Idea中SpringBoot多模块项目的建立实现

    2023-11-08 07:52:34
  • C# 调用Delphi dll 实例代码

    2023-06-12 22:46:06
  • android加密参数定位实现方法

    2022-05-03 08:28:55
  • SpringCloud使用Feign实现远程调用流程详细介绍

    2021-06-02 06:47:16
  • C#在Windows窗体控件实现内容拖放(DragDrop)功能

    2021-07-25 01:48:27
  • Android编程之ListView和EditText发布帖子隐藏软键盘功能详解

    2023-11-06 23:09:55
  • SpringBoot结合Vue实现投票系统过程详解

    2022-08-24 16:12:30
  • Java利用位运算实现乘法运算详解

    2023-03-19 20:29:24
  • 使用SpringMVC的@Validated注解验证的实现

    2023-09-20 19:49:55
  • Java剑指offer之删除链表的节点

    2023-05-19 15:30:27
  • 纯Java代码实现流星划过天空

    2022-06-01 12:12:35
  • Spring Boot整合mybatis使用注解实现动态Sql、参数传递等常用操作(实现方法)

    2023-03-17 07:09:32
  • 基于C#实现的三层架构实例

    2023-09-09 11:39:33
  • Java设计者模式简单工厂模式解析

    2023-02-07 14:02:54
  • Java实现批量下载选中文件功能

    2021-09-09 17:57:45
  • 关于Spring Boot项目的 log4j2 核弹漏洞问题(一行代码配置搞定)

    2022-08-26 03:04:20
  • Java面试题-实现复杂链表的复制代码分享

    2023-11-23 20:05:39
  • Java ==,equals()与hashcode()的使用

    2022-02-24 07:06:28
  • springboot从application.properties中注入list, map方式

    2023-11-28 23:42:33
  • winform基于异步委托实现多线程摇奖器

    2021-10-09 05:09:39
  • asp之家 软件编程 m.aspxhome.com