黑马程序员技术交流社区
标题:
用字节流读取文件,定义缓冲区的大小问题[ 已解决 ]
[打印本页]
作者:
郑传庆
时间:
2012-6-8 18:57
标题:
用字节流读取文件,定义缓冲区的大小问题[ 已解决 ]
本帖最后由 郑传庆 于 2012-6-8 21:51 编辑
用FileInputStream在读取文件的时候,定义缓冲区的大小用下面哪个比较好?它们在什么情况下使用比较合适?
byte[] buff = new byte[input.availabe()]和byte[] buff = new byte[1024]
作者:
杨天皓
时间:
2012-6-8 19:08
availabe()在有些 InputStream 的实现将返回流中的字节总数,但也有很多实现不会这样做。试图使用此方法的返回值分配缓冲区,以保存此流所有数据的做法是不正确的。
也就是说,因为网络传输的非实时性,在你的程序去检查available的时候,实际上另一端可能还没有发送数据,或对方网络拥挤,要发给你的数据包还在队列中。所以你调用 available时有可能 会返回0。
建议你还是用1024吧。
作者:
潘东升
时间:
2012-6-8 19:14
byte[] buff = new byte[input.availabe()]是根据读取流的剩余字节变化长度的,一般读取内容少的文件的时候用会效率高,因为刚刚好一次就把源文件读取到了缓冲中,但是在内容量大的文件读取的时候用这种方法,有可能会耗尽虚拟机的使用内存,进而内存溢出,导致读取失败。还有,这种方式在网络读取时需要一次不受阻塞地读取完,容易因异常而中断导致读取失败。byte[] buff = new byte[1024],而这种方法的缓冲是固定大小的,不会出现这种情况,因为未知文件的大小是不确定的,所以一般建议使用这种方式。
作者:
麦田守望者0812
时间:
2012-6-8 20:24
import java.io.*;
public class FileStreamDemo {
public static void main(String[] args) throws IOException {
//创建两个文件,face.gif是已经存在文件,newFace.gif是新创建的文件
File inFile = new File("face.gif");
File outFile = new File("newFace.gif");
//创建流文件读入与写出类
FileInputStream inStream = new FileInputStream(inFile);
FileOutputStream outStream = new FileOutputStream(outFile);
//通过available方法取得流的最大字符数
byte[] inOutb = new byte[inStream.available()];
inStream.read(inOutb); //读入流,保存在byte数组
outStream.write(inOutb); //写出流,保存在文件newFace.gif中
inStream.close();
outStream.close();
}
}
实例:读写任意大文件应用
因为byte数组最大存储值不超过64M,所以当一个文件大于60M 的时候,需要分开几个流操作。我们把上面的程序作一个修改,就可以写入任意大小的文件。这个程序应用了FileInputStream类的方法如下:
read(byte[] b,int off,int len)
把特定位置的流内容读入数组,已经读入byte[]数组的内容,会在流文件中删除。
程序运行的结果会产生一个新文件。
样例:
import java.io.*;
public class FileStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建两个文件
File inFile = new File("tcty36.rm");
File outFile = new File("newtcty36.rm");
//最大的流为60Mb,当文件的容量大于60Mb的时候便分开流
final int MAX_BYTE = 60000000;
long streamTotal = 0; //接受流的容量
int streamNum = 0; //流需要分开的数量
int leave = 0; //文件剩下的字符数
byte[] inOutb; //byte数组接受文件的数据
//创建流文件读入与写出类
FileInputStream inStream = new FileInputStream(inFile);
FileOutputStream outStream = new FileOutputStream(outFile);
//通过available方法取得流的最大字符数
streamTotal = inStream.available();
//取得流文件需要分开的数量
streamNum = (int)Math.floor(streamTotal/MAX_BYTE);
//分开文件之后,剩余的数量
leave = (int)streamTotal % MAX_BYTE;
//文件的容量大于60Mb时进入循环
if (streamNum > 0) {
for(int i = 0; i < streamNum; ++i){
inOutb = new byte[MAX_BYTE];
//读入流,保存在byte数组
inStream.read(inOutb, 0, MAX_BYTE);
outStream.write(inOutb); //写出流
outStream.flush(); //更新写出的结果
}
}
//写出剩下的流数据
inOutb = new byte[leave];
inStream.read(inOutb, 0, leave);
outStream.write(inOutb);
outStream.flush();
inStream.close();
outStream.close();
}
}
希望可以有帮助 固定数组缓冲区可以通过循环的方式读取任意大的文件 另一种方法 在文件过大的条件下 会过多占用电脑资源
作者:
朝哥
时间:
2012-6-8 21:35
数组在哪里,在堆内存中,java的堆内存大小是有限度,如果的文件是2G的话,用byte[] buff = new byte[input.availabe()]的话,堆内存是装不下的。但是你用byte[] buff = new byte[1024],每次数组存满1024的字节以后,就会回头重存数组。
还有java的堆内存肯定小于你计算机的内存。
作者:
王月
时间:
2012-6-8 21:47
available()
这个方法只有在读取的内容很少时,可以用。
还有因为它可以不受阻塞地读取的估计剩余字节数,但是在网速缓慢的网络上读取大文件时很可能会中断读取,导致失败。
建议使用
byte[] buff=new byte[1024],在这里它作为缓冲区是固定长度的,所以不会出现以上的问题
作者:
王月
时间:
2012-6-8 21:50
还有就是,avalible读取是一次就把所有的数据读取到缓冲区,而虚拟机的内存只有64M,所以在读取大文件时,很可能导致内存溢出.
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2