对文件的读取也是经常会遇到的操作,那么哪种方式效率更快呢,今天来做个测试。
首先能想到的就是,应该采用字节流对文件进行复制,文件可以是任何形式,如图片、视频、办公文档、压缩文件等等。
1、使用最基础的输入输出字节流
代码语言:javascript复制import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyFile {
public static void main(String[] args) {
//开始时间
long startTime = System.currentTimeMillis();
try {
//声明将文件内容读取到内存的节点流
FileInputStream fis = new FileInputStream("E:/Swagger.pdf");
//声明将内存数据写入到文件的节点流
FileOutputStream fos = new FileOutputStream("E:/Swagger_bak2.pdf");
int read = 0;
//按字节读取
while ((read = fis.read()) != -1){
//按字节写入
fos.write(read);
}
//刷新缓存到文件
fos.flush();
fos.close();
fis.close();
}catch (Exception e){
e.printStackTrace();
}
//结束时间
long endTime = System.currentTimeMillis();
//耗时
System.out.println((endTime - startTime));
}
}
输出: 1410
这种方法虽然可以完成文件复制功能,但是效率低,因为每个字节读取或写入,需要调用大量的磁盘IO操作。
2、在输入输出字节流中加入缓存
代码语言:javascript复制import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyFile {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream("E:/Swagger.pdf");
FileOutputStream fos = new FileOutputStream("E:/Swagger_bak.pdf");
//启用缓存
byte[] buf = new byte[1024];
int read = 0;
//从文件中一次读取缓存中定义的字节
while ((read = fis.read(buf)) != -1){
//向文件中一次写入缓存中定义的字节数据
fos.write(buf, 0, read);
}
fos.flush();
fos.close();
fis.close();
}catch (Exception e){
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println((endTime - startTime));
}
}
输出: 5
加入了缓存数组后,减少了磁盘IO操作,按块对源文件数据进行读取,并批量写入,可以看到,文件复制的效率提升非常明显。
需要注意的是:缓存块的大小定义要适中,太小起不到作用,太大会占用过多内存。
3、不使用缓存,仅使用字节缓冲流拷贝文件
代码语言:javascript复制import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyFile {
public static void main(String[] args) {
//开始时间
long startTime = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream("E:/Swagger.pdf");
FileOutputStream fos = new FileOutputStream("E:/Swagger_bak2.pdf");
//声明字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(fis);
//声明字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(fos);
int read = 0;
//将文件内容读取到缓冲流中
while ((read = bis.read()) != -1){
//将文件内容写入到字节缓冲流
bos.write(read);
}
bos.flush();
bos.close();
bis.close();
}catch (Exception e){
e.printStackTrace();
}
//结束时间
long endTime = System.currentTimeMillis();
//耗时
System.out.println((endTime - startTime));
}
}
输出: 22
从输出的耗时来看,这种方式的效率,也明显优于单纯的使用字节节点流来实现文件的拷贝,但是相比缓存方式读取,效率还是较差。
4、字节缓冲流加缓存,实现文件复制
代码语言:javascript复制import java.io.FileInputStream;
import java.io.FileOutputStream;
public class CopyFile {
public static void main(String[] args) {
//开始时间
long startTime = System.currentTimeMillis();
try {
FileInputStream fis = new FileInputStream("E:/Swagger.pdf");
FileOutputStream fos = new FileOutputStream("E:/Swagger_bak2.pdf");
//声明字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(fis);
//声明字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(fos);
//声明缓存
byte[] buf = new byte[1024];
int read = 0;
//采用缓冲流,读写缓存数据
while ((read = bis.read(buf)) != -1){
bos.write(buf, 0, read);
}
bos.flush();
bos.close();
bis.close();
}catch (Exception e){
e.printStackTrace();
}
//结束时间
long endTime = System.currentTimeMillis();
//耗时
System.out.println((endTime - startTime));
}
}
输出: 2
采用这种方式,同时使用的缓冲流和缓存技术,进一步提升了文件的读写效率,适当增大缓存数组,充分利用内存实现文件的极速复制。
总结:
文件复制的效率依次为:
字节流 < 缓冲流 < 缓存 < 缓冲流 缓存