java为什么要刷新缓冲区?java中flush()刷新缓冲区有什么作用
今天给各位分享java为什么要刷新缓冲区的知识,其中也会对java中flush()刷新缓冲区有什么作用进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
关于java的io读写,缓冲区是如何提高读写效率的
给你一个例子自己看看吧,加深理解
我们知道Java中一般的输入输出流类都是用单字节的读取方法来进行I/O操作的,也就是说每次只读写一个字节的数据,这种方法显然繁琐低效。如果从设备读取10M的文件,每次读取一个字节,完成操作将需要做10M/次I/O操作,I/O操作又是一件相当耗时的事情,无疑在很大程度上降低了系统的性能。
Java中专门提供提高I/O效率的缓冲类,这好比在数据读写时提供一个临时缓冲区,每次读取一个缓冲区大小的数据,将这数据库一次性写入目标设备。下图中分别为两种读取方式。
举个简单例子,在A地有10000本书需要搬到B地,如果一次搬1本,需要10000次。如果每次取1000本放到一个货车上,运到B地,需要10次完成。货车相当于是缓存区。同样道理,开设一个数据缓存区每次读取一数据块对于提高读取效率有显著提升。下面用一个具体代码示例来表示二者的性能差别。
Java代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class TestBuffer{
public static void main(String args[]) throws IOException{
String from="f:/1.MP3";
System.out.println(from);
long startTime1= System.currentTimeMillis();
TestBuffer.readWriteWithBuffer(from,"f:/2.MP3");
long endTime1= System.currentTimeMillis();
System.out.println("使用缓冲区读取耗时:"+(endTime1- startTime1)+"ms");
long startTime= System.currentTimeMillis();
TestBuffer.readWrite(from,"f:/3.MP3");
long endTime= System.currentTimeMillis();
System.out.println("直接读取耗时:"+(endTime- startTime)+"ms");
}
public static void readWrite(String from, String to) throws IOException{
InputStream in= null;
OutputStream out= null;
try{
in= new FileInputStream(from);
out= new FileOutputStream(to);
while(true){
int data= in.read();
if(data==-1){
break;
}
out.write(data);
}
} finally{
if(in!= null){
in.close();
}
if(out!= null){
out.close();
}
}
}
/***************************************************************************
*使用缓存区读写文件
*@param from
*@param to
*@throws IOException
*/
public static void readWriteWithBuffer(String from, String to)
throws IOException{
InputStream inBuffer= null;
OutputStream outBuffer= null;
try{
inBuffer= new BufferedInputStream(new FileInputStream(from));
outBuffer= new BufferedOutputStream(new FileOutputStream(to));
while(true){
int data= inBuffer.read();
if(data==-1){
break;
}
outBuffer.write(data);
}
} finally{
if(inBuffer!= null){
inBuffer.close();
}
if(outBuffer!= null){
outBuffer.close();
}
}
}
}
运行例子时会根据mp3文件的大小决定运行时间的长短,尽量使用小一点的mp3文件,运行时需耐心等待一段时间
Java中IO缓冲区的原理是什么
如果是边读边写,就会很慢,也伤硬盘。缓冲区就是内存里的一块区域,把数据先存内存里,然后一次性写入,类似数据库的批量操作,这样效率比较高。
调用I\O操作的时候,实际上还是一个一个的读或者写,关键就在,CPU只有一个,不论是几个核心。CPU在系统调用时,会不会还要参与主要操作?参与多次就会花更多的时间。
系统调用时,若不用缓冲,CPU会酌情考虑使用中断。此时CPU是主动地,每个周期中都要花去一部分去询问I\O设备是否读完数据,这段时间CPU不能做任何其他的事情(至少负责执行这段模块的核不能)。所以,调用一次读了一个字,通报一次,CPU腾出时间处理一次。
而设置缓冲,CPU通常会使用 DMA方式去执行 I\O操作。CPU将这个工作交给DMA控制器来做,自己腾出时间做其他的事,当DMA完成工作时,DMA会主动告诉CPU“操作完成”。这时,CPU接管后续工作。在此,CPU是被动的。DMA是专门做 I\O与内存数据交换的,不仅自身效率高,也节约了CPU时间,CPU在DMA开始和结束时做了一些设置罢了。
所以,调用一次,不必通报CPU,等缓冲区满了,DMA会对C PU说“嘿,伙计!快过来看看,把他们都搬走吧”。
综上,设置缓冲,就建立了数据块,使得DMA执行更方便,CPU也有空闲,而不是呆呆地候着I\O数据读来。从微观角度来说,设置缓冲效率要高很多。尽管,不能从这个程序上看出来。几万字的读写\就能看到差距
java中如何使用缓冲区对文件进行读写操作
首先,了解下什么是缓冲区:
电脑内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈——就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
堆——就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
自由存储区——就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
全局/静态存储区——全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改)
电脑缓冲区就是预留下来的做为急用的那一部分,为暂时置放输出或输入资料的内存。
如何对缓冲区进行操作:
当我们读写文本文件的时候,采用Reader是非常方便的,比如FileReader,InputStreamReader和BufferedReader。其中最重要的类是InputStreamReader,它是字节转换为字符的桥梁。你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。使用FileReader读取文件:
FileReader fr= new FileReader("ming.txt");
int ch= 0;
while((ch= fr.read())!=-1)
{
System.out.print((char)ch);
}
其中read()方法返回的是读取得下个字符。当然你也可以使用read(char[] ch,int off,int length)这和处理二进制文件的时候类似。
事实上在FileReader中的方法都是从InputStreamReader中继承过来的。read()方法是比较好费时间的,如果为了提高效率我们可以使用BufferedReader对Reader进行包装,这样可以提高读取得速度,我们可以一行一行的读取文本,使用readLine()方法。
BufferedReader br= new BufferedReader(new InputStreamReader(new FileInputStream("ming.txt")));
String data= null;
while((data= br.readLine())!=null)
{
System.out.println(data);
}
了解了FileReader操作使用FileWriter写文件就简单了,这里不赘述。
Eg.我的综合实例:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class testFile{
/**
*@param args
*/
public static void main(String[] args){
// TODO Auto-generated method stub
// file(内存)----输入流---->【程序】----输出流---->file(内存)
File file= new File("d:/temp","addfile.txt");
try{
file.createNewFile();//创建文件
} catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
//向文件写入内容(输出流)
String str="亲爱的小南瓜!";
byte bt[]= new byte[1024];
bt= str.getBytes();
try{
FileOutputStream in= new FileOutputStream(file);
try{
in.write(bt, 0, bt.length);
in.close();
// boolean success=true;
// System.out.println("写入文件成功");
} catch(IOException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch(FileNotFoundException e){
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
//读取文件内容(输入流)
FileInputStream out= new FileInputStream(file);
InputStreamReader isr= new InputStreamReader(out);
int ch= 0;
while((ch= isr.read())!=-1){
System.out.print((char) ch);
}
} catch(Exception e){
// TODO: handle exception
}
}
}
java中flush()刷新缓冲区有什么作用
我的理解:输出流呢,类似于一根管道,输出的时候先放到管道里,然后管道满了存到介质上(硬盘或其他地方),当我们输出完后管道里面可能还有剩余,就用flush()清空管道即全部存到介质上。好象java默认的缓冲区是8kb?(我也忘了),就是说只有每填满8kb才会提交一次,当少于这个值时就不会提交,所以最后为防止有未提交数据就flush()一下,强行提交生于数据
也就是说,一般输出流关闭之前要用下这个方法。
关于java为什么要刷新缓冲区,java中flush()刷新缓冲区有什么作用的介绍到此结束,希望对大家有所帮助。