黑马程序员_关于JAVA中流缓冲区的效率探索

本文通过实验对比不同读写方式的效率,分析了BufferedReader相较于FileReader的优势,并探讨了同步判断对性能的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

       

       关于流缓冲区的效率探索,是从看毕向东老师的JAVA基础视频,产生的疑问开始的。毕老师视频里编写的字节流缓冲器MyBufferedInputStream复制一个Mp3是三百多毫秒,用JAVA库中的BufferedInputStream复制同样的Mp3是五百多毫秒。原理应该是一样的,为什么毕老师的要快,那JAVA库里的BufferedInputStream为什么不优化一下?经过网友的提示,我查看了BufferedInputStream.java的源代码,发现其中大多数的语句都是加了synchronized关键词修饰的,之前学过,同步判断是很影响效率的,尤其是示例程序中,每读取一个字节都要进行一次锁判断,所以导致了BufferedInputStream类的读取速度较慢,而毕老师的MyBufferedInputStream没有任何的同步判断,所以效率要高,速度明显快的多。如果文件更大一些,差距应该更大。

       另外,我想研究一下有缓冲区到底比不用缓冲区快多少。于是我自己编了个小程序做试验,程序中的copyfile.txt是个两百多kb的文件。

import java.io.*;
class CopySpeedTest
{
	public static void main(String[] args)throws IOException 
	{
		long start=System.currentTimeMillis();	
		copy1();
		long end=System.currentTimeMillis();
		System.out.println("copy1用时:"+(end-start)+"毫秒");
		start=System.currentTimeMillis();	
		copy2();
		end=System.currentTimeMillis();
		System.out.println("copy2用时:"+(end-start)+"毫秒");
		start=System.currentTimeMillis();	
		copy3();
		end=System.currentTimeMillis();
		System.out.println("copy3用时:"+(end-start)+"毫秒");	
	}
	//使用FileReader的read方法一个字符一个字符读取
	public static void copy1()throws IOException
	{
		FileReader fr=new FileReader("copyfile.txt");
		FileWriter fw=new FileWriter("copyfile_copy.txt");
		int i;
		while((i=fr.read())!=-1)
		{
			fw.write(i);
			//fw.flush();
		}
		fr.close();
		fw.close();
	}
	//使用BufferedReader的read方法,一个字符一个字符读取
	public static void copy2()throws IOException
	{
		FileReader fr=new FileReader("copyfile.txt");
		BufferedReader br=new BufferedReader(fr);
		FileWriter fw=new FileWriter("copyfile_copy.txt");
		BufferedWriter bw=new BufferedWriter(fw);
		int i;
		while((i=br.read())!=-1)
		{
			bw.write(i);
			//bw.flush();
		}
		fr.close();
		bw.close();
	}
	//使用LineNumberReader的行读取方法
	public static void copy3()throws IOException
	{
		FileReader fr=new FileReader("copyfile.txt");
		LineNumberReader lnr=new LineNumberReader(fr);
		FileWriter fw=new FileWriter("copyfile_copy.txt");
		BufferedWriter bw=new BufferedWriter(fw);
		String line=null;
		while((line=lnr.readLine())!=null)
		{
			bw.write(line);
			//bw.flush();
		}
		fr.close();
		bw.close();
	}
}
       输出结果:(多次运行过,除去cpu切换执行其他进程时的特殊情况,结果跟一下结果相差不多)

copy1用时:91毫秒
copy2用时:39毫秒
copy3用时:15毫秒

       直接使用FilerReader的read方法是最慢的,而使用行读取的LineNumberReade是最快的。(另外,如果每个循环中加入flush(),那更是会慢到难以想象。。。所以建议数据多一点再flush())

       我有疑问的是,copy1()和copy2()方法的差距,两个都是一个一个读取,理论上速度应该差不多啊,为什么有缓冲区会快呢?后来我看了Reader的和 InputStreamReader源码,发现Reader的read方法每读取一个字符,都会调用一次系统读取数据,而用BufferedReader的read方法,它会默认读取8kb的数据,用数组存放起来,然后每次调用read,返回数组相应角标的数据。所以会明显快的多。

       因此,如果说BufferedReader是对于FileReader的性能增强,是非常明显的,当然还有其他优点1、功能增强。 2、性能提高。3、安全性提高。(线程安全,即使是增加了锁判断的语句,性能依然比直接用Reader中的方法效率高)


---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值