我们知道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文件,运行时需耐心等待一段时间
方式一/**
* 以字节为单位读取文件,常用于读二进制文件,如图片、声音、影像等文件。
* 当然也是可以读字符串的。
*/
/* 貌似是说网络环境中比较复杂,每次传过来的字符是定长的,用这种方式?*/
public String readString1()
{
try
{
//FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。
FileInputStream inStream=this.openFileInput(FILE_NAME)
ByteArrayOutputStream bos = new ByteArrayOutputStream()
byte[] buffer=new byte[1024]
int length=-1
while( (length = inStream.read(buffer) != -1)
{
bos.write(buffer,0,length)
// .write方法 SDK 的解释是 Writes count bytes from the byte array buffer starting at offset index to this stream.
// 当流关闭以后内容依然存在
}
bos.close()
inStream.close()
return bos.toString()
// 为什么不一次性把buffer得大小取出来呢?为什么还要写入到bos中呢? return new(buffer,"UTF-8") 不更好么?
// return new String(bos.toByteArray(),"UTF-8")
}
}
方式二
// 有人说了 FileReader 读字符串更好,那么就用FileReader吧
// 每次读一个是不是效率有点低了?
private static String readString2()
{
StringBuffer str=new StringBuffer("")
File file=new File(FILE_IN)
try {
FileReader fr=new FileReader(file)
int ch = 0
while((ch = fr.read())!=-1 )
{
System.out.print((char)ch+" ")
}
fr.close()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
System.out.println("File reader出错")
}
return str.toString()
}
方式三
/*按字节读取字符串*/
/* 个人感觉最好的方式,(一次读完)读字节就读字节吧,读完转码一次不就好了*/
private static String readString3()
{
String str=""
File file=new File(FILE_IN)
try {
FileInputStream in=new FileInputStream(file)
// size 为字串的长度 ,这里一次性读完
int size=in.available()
byte[] buffer=new byte[size]
in.read(buffer)
in.close()
str=new String(buffer,"GB2312")
} catch (IOException e) {
// TODO Auto-generated catch block
return null
e.printStackTrace()
}
return str
}
/*InputStreamReader+BufferedReader读取字符串 , InputStreamReader类是从字节流到字符流的桥梁*/
/* 按行读对于要处理的格式化数据是一种读取的好方式 */
private static String readString4()
{
int len=0
StringBuffer str=new StringBuffer("")
File file=new File(FILE_IN)
try {
FileInputStream is=new FileInputStream(file)
InputStreamReader isr= new InputStreamReader(is)
BufferedReader in= new BufferedReader(isr)
String line=null
while( (line=in.readLine())!=null )
{
if(len != 0) // 处理换行符的问题
{
str.append("\r\n"+line)
}
else
{
str.append(line)
}
len++
}
in.close()
is.close()
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace()
}
return str.toString()
}
根据网上大神的说法: 使用缓冲流,能提高文件的读写效率.BufferedOutputStream bout = new BufferedOutputStream(out)
int len =0
byte[] buf = new byte[1024]
.......
但是经本人测试,好像没什么区别,不知道他们说的大型文件是多少,我用1.2M的txt测试读写,时间没差多少,可能过G的文件,效率应该比较明显一点吧
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)