关于流,看了2天,但是依旧没看懂,所以决定痛下决心,一点点从概念搞清楚,再来看。
可视化来表达,确实要比文字表述的清楚,下面发张图片以便于理解。关于流,以下是我的理解,不对的地方请大家纠正!!谢谢!!!1、我觉的内存是一个双向输入、输出设备。以从硬盘读、写文件为例。当内存改写硬盘中的文件时,既变成了输出设备,并且通过输出流传向硬盘,此时硬盘既变成了一个输入设备。
这里就联想到另一个问题了:关于向输出流写入数据时,数据是被传送到缓冲区而不是外部设备。只有缓冲区满了才被送往外设。如果希望在缓冲区满之前传送,那么我们可以通过刷新来实现。那么当保存数据时呢??难道 保存==刷新??2、同理,当我们要读取硬盘文件时,此时硬盘既变成了一个输出设备,通过传送输出流被内存(此时既变成了输入设备)的缓冲区接收。
这里又有一个概念问题了:如果此时缓冲为空,且程序已经请求数据时,对作为流的数据源设备的读操作才会进行。当发生这种情况时,如果外设能提供足够的数据,就会自动地从外设读取数据直至缓冲区全满。这句话我的理解是:如果缓冲区的大小是500KB,而此次请求的数据量是1MB。那么数据以500KB的大小填满缓冲区,但是如果此次请求是300KB,那么就直接从外设读取,而省略从外设到缓冲区再被调用,这一个步骤。真心希望能得到大家,具体详细的回答!!下面是图片:
可视化来表达,确实要比文字表述的清楚,下面发张图片以便于理解。关于流,以下是我的理解,不对的地方请大家纠正!!谢谢!!!1、我觉的内存是一个双向输入、输出设备。以从硬盘读、写文件为例。当内存改写硬盘中的文件时,既变成了输出设备,并且通过输出流传向硬盘,此时硬盘既变成了一个输入设备。
这里就联想到另一个问题了:关于向输出流写入数据时,数据是被传送到缓冲区而不是外部设备。只有缓冲区满了才被送往外设。如果希望在缓冲区满之前传送,那么我们可以通过刷新来实现。那么当保存数据时呢??难道 保存==刷新??2、同理,当我们要读取硬盘文件时,此时硬盘既变成了一个输出设备,通过传送输出流被内存(此时既变成了输入设备)的缓冲区接收。
这里又有一个概念问题了:如果此时缓冲为空,且程序已经请求数据时,对作为流的数据源设备的读操作才会进行。当发生这种情况时,如果外设能提供足够的数据,就会自动地从外设读取数据直至缓冲区全满。这句话我的理解是:如果缓冲区的大小是500KB,而此次请求的数据量是1MB。那么数据以500KB的大小填满缓冲区,但是如果此次请求是300KB,那么就直接从外设读取,而省略从外设到缓冲区再被调用,这一个步骤。真心希望能得到大家,具体详细的回答!!下面是图片:
楼主【llm0528】截止到2008-07-03 11:29:32的历史汇总数据(不包括此帖):
发帖的总数量:39 发帖的总分数:780
结贴的总数量:37 结贴的总分数:740
无满意结贴数:0 无满意结贴分:0
未结的帖子数:2 未结的总分数:40
结贴的百分比:94.87 % 结分的百分比:94.87 %
无满意结贴率:0.00 % 无满意结分率:0.00 %
值得尊敬
int
呵呵.!!
找点小的例子
多写写
就能明白!
愿楼主好运.!!
I/O 是最基本的知识,这也跳过那还学 Java 干嘛?
package com.dwr.study;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Fileone { public static void main(String args[]) { File file = new File("d:/1.gif");
File file2 = new File("d:/11.gif"); FileInputStream fio = null;
FileOutputStream fot = null;
try {
fio = new FileInputStream(file);
fot = new FileOutputStream(file2); BufferedInputStream inputBuffer = new BufferedInputStream(fio);
BufferedOutputStream outputBuffer = new BufferedOutputStream(fot);
byte[] io1 = new byte[100000];
int reads = 0; while ((reads = inputBuffer.read(io1, 0, 100000)) >= 0) {
System.out.println(reads + "======");
outputBuffer.write(io1, 0, reads);
}
outputBuffer.flush();
//刷新此缓冲的输出流。这迫使所有缓冲的输出字节被写出到基础输出流中
fio.close();
//关闭此文件输入流并释放与此流有关的所有系统资源。
//如果此流有一个与之关联的通道,则关闭该通道。 fot.close(); } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }}
保存==刷新 你说的保存等于刷新,刷新也就是仅仅是保存数据,而关闭 ,就不仅仅是保存数据还要释放资源!
最好用 用关闭来保存,这样可以释放一些资源。我想说的是,不管你的反冲区多大,也不管你的数据量是多大,都要经过 返冲区的我认为!
以下是我个人想法,不知道对不对,其实 所谓的反冲区,不是 BufferedInputStream 而是我们自己定义的数组byte[] io1 = new byte[100000];
每次,读取和写入都是通过这个数组来完成,这个数组才是我们真整的反冲区, 象
BufferedInputStream , BufferedReader (Reader的数组是char 类型) 等等只不过是提供了一些其他的特殊的方法,而他们还是要通过一个特定的 类似于 byte[] io1 = new byte[100000]; 这样的数组(反冲)来完成相应的操作!
回答楼主问题
1.我认为,保存的时候,肯定是要刷新一下的.不刷新的话,肯定会导致有数据写不上的.关闭文件的时候同样也要刷新,因为你关任何文件的时候,他都会问你是否保存,也相当于问你是否刷新.(如果楼主说的刷新指flush()的话) 楼主可以调一下自己的电脑,设置成显示隐藏文件,然后打开个word文档你往上写东西,你就会看到文件的旁边多了一个隐藏的文件文件名以~$开头,这个以~$开头的文件,你就把他当成是一个无限大缓存区,你写东西时,其实是写在这个~$开头的文件上,只有当你保存的时候,才flush()到你真正要写的那个文件上.
不知讲明白没有,希望你能理解...2.如果你想用Bufferedxxxxxx,那这就是带缓存的输入或输出(这时你不要去想你自己电脑配置的什么二级缓存啊,什么内存啊,不要去想你电脑里的) 假设缓存区是500K,你就把他当做一个能成500斤的一个大桶,旁边有一个超级大水池,水池想要1000斤的水,你要先拿你的大桶装水,装满一桶就是500斤,要满足水池那1000斤的需要,你就得给他两大桶水.
那如果水池要300斤水,你同样也是拿你的大桶往里倒水,只不过这次不用装满你的大桶,只需把你的大桶装满3/5就行了,然后把这桶未满的水倒入水池,水池这300斤的需求也满足了.
不用管水池要多少水,你就记住你往里倒水必须用桶!管他是装满一桶还是装几分之几桶.总之是用桶往里倒水.
如果你不用带Buffered的输入输出系统.
那你就想做是水池要水的话,你只能一滴水一滴水的往水池里送,(用什么送就不用管了...),你要频繁的去访问这个水池.(这样的话估计水池坏的也快).所以,用Buffered会减少对水池的损坏.
不知说明白没,希望你理解..