带缓存的输入/输出流

缓存是I/O的一种性能优化。缓存流为I/O流增加了内存缓存区。有了缓存区,使得在流上执行skip()、 mark() 和 reset() 方法都成为可能。

1.BufferedInputStream与BufferedOutputStream类

BufferedInputStream类可以对所有InputStream类进行带缓存区的包装以达到性能的优化。BufferedInputStream类有两个构造方法:

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

第一种形式的构造方法创建了一个带有32个字节的缓存流;第二种形式的构造方法按指定的大小来创建缓存区。一个最优的缓存区的大小,取决于它所在的操作系统、可用的内存空间以及机器配置。从构造方法可以看出,BufferedInputStream对象位于InputStream类对象之前,下图描述了字节数据读取文件的过程:
BufferedInputStream读取文件过程
使用BufferedOutputStream输出信息和利用OutputStream输出信息完全一样,只不过BufferedOutputStream有一个flush()方法用来将缓存区的数据强制输出完。BufferedOutputStream类也有两个构造方法:

  • BufferedOutputStream(OutputStream in)
  • BufferedOutputStream(OutputStream in, int size)

第一种构造方法创建一个有32个字节的缓存区,第二种构造方法以指定的大小来创建缓存区。

flush()方法就是用于即使在缓存区没有满的情况下,也将缓存区的内容强制写入到外设,习惯上称这个过程为刷新。flush()方法只对使用缓存区的OutputStream类的子类有效。当调用close()方法时,系统在关闭流之前,也会将缓存区中的信息刷新到新的磁盘文件中。

2.BufferedReader与BufferedWriter类

BufferedReader类与BufferedWriter类分别继承Reader类与Writer类。这两个类同样具有内部缓存机制,并可以以行为单位进行输入/输出。

根据BufferedReader类的特点,总结出下面字符数据读取文件的过程:
在这里插入图片描述
BufferedReader类常用的方法如下:

方法说明
read()读取单个字符
readLine()读取一个文本行,并将其返回为字符串。若无数据可读,则返回null。BufferedWriter类中的方法都返回void
write(String s, int off, int len)写入字符串的某一部分
flush()刷新该流的缓存
newLine()写入一个行分隔符

在使用BufferedWriter类的Write()方法时,数据并没有立刻被写入输出流,而是首先进入缓存区中,如果想立刻将缓存区中的数据写入输出流,一定要调用flush()方法。

public class Student{ //创建类
	public static void main(String args[]){ //主方法
		String content[] = {"好久不见","最近好吗","常联系"}; //定义字符串数组
		File file = new File("world.txt"); //创建文件对象
		try{
			FileWriter fw = new FileWriter(file); //创建FileWriter类对象
			BufferedWriter bufw = new BufferedWriter(fw); //创建BufferedWriter类对象
			for(int k=0;k<content.lenth;k++){ //循环遍历数组
				bufw.write(content[k]); //将字符串数组中的元素写入到磁盘文件中
				bufw.newLine(); //将数组中的单个元素以单行的形式写入文件
			}
			bufw.close(); //将BufferedWriter流关闭
			fw.close(); //将FileWriter流关闭
		}catch(Exception e){
			e.printStackTrace(); //处理异常
		}
		try{
			FileReader fr = new FileReader(file); //创建FileReader类对象
			BufferedReader bufr = new BUfferedReader(fr); //创建BufferedReader类对象
			String s = null; //创建字符串变量
			int i = 0; //生命int型变量
			//如果文件的文本行数不为null,则进入循环
			while((s = bufr.readLine()) != null){
				i++; //将变量做自增运算
				System.out.println("第"+ i + "行:" + s); //输出文件数据
			}
			bufr.close(); //将FileReader流关闭
			fr.close(); //将FileReader流关闭
		}catch(Exception e) {
			e.printStackTrace(); //处理异常
		}
	}
}

3.数据输入/输出流

数据输入/输出流(DataInputStream类与DataOutputStream类)允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。也就是说,当读取一个数据时,不必再关心这个数值应当是哪种字节。

DataInputStream类与DataOutputStream类的构造方法如下:

  • DataInputStream(InputStream in):使用指定的基础InputStream创建一个DataInputStream。
  • DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。

DataOutputStream类提供了如下3种写入字符串的方法。

  • writeBytes(String s)
  • writeChars(String s)
  • writeUTF(String s)

由于Java中的字符是Unicode编码,是双字节的,writeBytes只是将字符串中的每一个字符的低字节内容写入目标设备中;而writeChars将字符串中的每一个字符的两个字节的内容都写到目标设备中;writeUTF将字符串按照UTF编码后的字节长度写入目标设备,然后才是每一个字节的UTF编码。

DataInputStream类只提供了一个readUTF()方法返回字符串。这是因为要在一个连续的字节流读取一个字符串,如果没有特殊的标记作为一个字符串的结尾,并且不知道这个字符串的长度,就无法指导读取到什么位置才是这个字符串的结束。DataOutputStream类中只有writeUTF()方法向目标设备中写入字符串的长度,所以也能准确地读回写入字符串。

public class Example_01{
	public static void main(String[] args){
		try{
			FileOutputStream fs = new FileOutputStream("world.txt"); //创建FileOutputStream对象
			DataOutputStream ds = new DataOutputStream(fs); //创建DataOutputStream对象
			
			ds.writeUTF("使用writeUTF()方法写入数据;"); //写入磁盘文件数据
			ds.writeChars("使用writeChars()方法写入数据;"); 
			ds.writeBytes("使用writeBytes()方法写入数据;");
			ds.close(); //将流关闭
			FileInputStream fis = new FileInputStream("word.txt"); //创建FileInputStream对象

			DataInputStream dis = new DataInputStream("fis"); //创建DataInputStream对象

			System.out.print(dis.readUTF()); //将文件数据输出
		}catch(Exception e){
			e.printStackTrace() //输出异常信息
		}
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值