话题:假设机器只有500M内存,有一个1.23GB的文件,要从一个目录复制到另外一个目录
目的:比较IO与NIO的读取速度效率
细节:大文件不能一次读到内存中,否则会内存溢出,只能每次读取固定大小的数据流
下面进行代码实现,在实现代码中,有的代码是一次性读取全部内容到内存中,有的是读取固定大小,分别看看这些方法读取文件速度的差异
文件大小 1.23GB
1.使用RandomAccessFile读取文件,FileOutputStream写文件,耗时:8768ms
2.使用BufferedInputStream读取文件,BufferedOutputStream写文件,耗时:2202ms
3.使用Scanner读文件,FileOutputStream写文件,耗时:120945ms
4.使用NIO,FileChannel读写文件,耗时:
基本上使用NIO和有缓冲区的IO–BufferedInputStream读写文件速度最快,通过任务管理器观察对内存的使用基本在100M上下浮动
package com.zypcy.readbigfile;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Scanner;
/**
* 读取大文件
* 分别测试不同文件流IO与NIO读取的效率
* 因文件很大,机器可用内存较小,无法一次读取全部内容,需要读取固定大小的数据
* @author zhuyu
*/
public class Demo {
public static void main(String[] args) {
String filePath = "D:\\project\\java\\workspace\\DemoThread\\src\\com\\zypcy\\readbigfile\\bigdata.zip";
String newPath = "D:\\project\\java\\workspace\\DemoThread\\src\\com\\zypcy\\readbigfile\\output.zip";
try {
File file = new File(filePath);
if(!file.exists()){
return;
}
File newFile = new File(newPath);
//randomAccessRead(file ,newFile);
//测试:读取1.23GB文件耗时:8768ms
//bufferedRead(file ,newFile);
//测试:读取1.23GB文件耗时:2202ms
//scannerRead(file ,newFile);
//测试:读取1.23GB文件耗时:120945ms
fileChannelRead(file ,newFile);
//每次读取1M,耗时:8947ms
//每次读取5M,耗时:2976ms
//每次读取10M,耗时:1802ms
//每次读取20M,耗时:1279ms
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 使用 RandomAccessFile 读取文件
* @param file
* @param newFile
*/
public static void randomAccessRead(File file , File newFile){
//测试:读取1.23GB文件耗时:8768ms
long d1 = System.currentTimeMillis();
RandomAccessFile raf = null;
OutputStream output = null;
try {
raf = new RandomAccessFile(file , "rw");
output = new FileOutputStream(newFile);
int len = 0; //每次读取内容长度
byte[] data = new byte[1024];//内容缓冲区
while((len = raf.read(data)) != -1){
output.write(data, 0, len);
}
long d2 = System.currentTimeMillis();
System.out.println("randomAccessRead读取完成,耗时:" + (d2 - d1));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(raf != null){
raf.close();
}
if(output != null){
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用NIO的FileChannel读取
* @param file
* @param newFile
*/
public static void fileChannelRead(File file , File newFile){
//1.23GB文件
//每次读取1M,耗时:8947ms
//每次读取5M,耗时:2976ms
//每次读取10M,耗时:1802ms
//每次读取20M,耗时:1279ms
long d1 = System.currentTimeMillis();
FileInputStream in = null;
FileOutputStream output = null;
FileChannel fic = null;
FileChannel foc = null;
try {
in = new FileInputStream(file);
output = new FileOutputStream(newFile);
fic = in.getChannel();
foc = output.getChannel();
//fic.transferTo(0, fic.size(), foc);
ByteBuffer buf = ByteBuffer.allocate(20480);
while(fic.read(buf) != -1){
buf.flip();//切换到读取数据模式
foc.write(buf);//将缓冲区的数据写入通道中
buf.clear();//清空缓冲区
}
long d2 = System.currentTimeMillis();
System.out.println("fileChannelRead读取完成,耗时:" + (d2 - d1));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(in != null){
in.close();
}
if(output != null){
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用IO的缓冲区读取
* @param file
* @param newFile
*/
public static void bufferedRead(File file , File newFile){
//测试:读取1.23GB文件耗时:2202
long d1 = System.currentTimeMillis();
InputStream in = null;
OutputStream output = null;
try {
in = new BufferedInputStream(new FileInputStream(file)) ;
output = new BufferedOutputStream(new FileOutputStream(newFile));
int len = 0;
byte[] data = new byte[1024];
while((len = in.read(data)) != -1){
output.write(data, 0, len);
}
long d2 = System.currentTimeMillis();
System.out.println("bufferedRead读取完成,耗时:" + (d2 - d1));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(in != null){
in.close();
}
if(output != null){
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 使用Scanner一行一行读取
* @param file
* @param newFile
*/
public static void scannerRead(File file , File newFile){
//读取1.23GB文件耗时:120945
long d1 = System.currentTimeMillis();
InputStream in = null;
OutputStream output = null;
try {
in = new FileInputStream(file);
output = new FileOutputStream(newFile);
Scanner sc = new Scanner(in, "UTF-8");
//sc.useDelimiter("\\r\\n");
while(sc.hasNext()){
String content = sc.nextLine();
output.write(content.getBytes("UTF-8"));
}
long d2 = System.currentTimeMillis();
System.out.println("scannerRead读取完成,耗时:" + (d2 - d1));
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(in != null){
in.close();
}
if(output != null){
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
文章浏览阅读2.1k次,点赞3次,收藏13次。研究生论文写作步骤1. 先看综述,后看论著。看综述搞清概念,看论著掌握方法。2. 早动手在师兄师姐离开之前学会关键技术。3. 多数文章看摘要,少数文章看全文。掌握了一点查全文的技巧,往往会以搞到全文为乐,以至于没有时间看文章的内容,更不屑于看摘要。真正有用的全文并不多,过分追求全文是浪费,不可走极端。当然只看摘要也是不对的。4. 集中时间看文献,看过总会遗忘。看文献的时间越分散_研究生一天读多少文献
文章浏览阅读547次。【科技犬体验】2019年10月15日,智米正式推出了旗下电暖器新品——智米电暖器1S和智米电暖器智能版1S对于没有集中供暖的长江中下游地区居民而言,电暖器是不折不扣的"保命神器"。而在深秋的北方,昼夜温差较大,这种时候使用灵活、易于搬运的电暖器也成为更加明智的选择。在北方每年的冬季,室内温度就直接关系着大家在家的舒适度,而对于室内温度不达标的用户,购买电暖器就成为几乎唯一的选择。科技犬已经入手智米..._智米电暖器智能版app
文章浏览阅读312次。本节书摘来自华章计算机《Hadoop与大数据挖掘》一书中的第2章,第2.6节,作者 张良均 樊哲 位文超 刘名军 许国杰 周龙 焦正升,更多章节内容可以访问云栖社区“华章计算机”公众号查看。2.6 TF-IDF算法原理及Hadoop MapReduce实现2.6.1 TF-IDF算法原理原理:在一份给定的文件里,词频(Term Frequency,..._hadoop mapreduce如何实现实现tf-idf
文章浏览阅读4.3k次。刚完成一个客户需求,同一个页面上要有点击缩略图查看大图功能,也有点击图片名称查看原图的功能。点击缩略图查看大图的功能点击缩略图查看大图的功能实现用的是layui开发文档内的layer.photos-相册层。官方开发文档里photos支持传入json和直接读取页面图片两种方式。下面是官方开发文档的截图,官方开发文档链接:https://www.layui.com/doc/m..._layui查看图片
文章浏览阅读89次。ueditor下载好之后直接复制到项目的WebContent目录下,并将ueditor\jsp\lib下的jar包复制或者剪切到项目的lib目录下。先看一下效果,如下:v1.文件的上传 首先在ueditor/jsp目录下找到config.json文件,就拿Image上传来说吧。 "imageUrlPrefix": "http:/..._ueditor json = new function("return " + result)();
文章浏览阅读6.5k次,点赞7次,收藏59次。基本思想:最近想尝试一下nano 上部署nanodet,于是记录一下训练过程,手中有一份labelme标注的数据集,于是开始了一波操作~首先将图片和json数据集转成xml (https://blog.csdn.net/sxj731533730/article/details/90046780),然后将xml数据集转成voc;import sysimport osimport jsonimport xml.etree.ElementTree as ETfrom PIL import Im_nanodet
文章浏览阅读107次。emmm…今天新搭了一套虚拟机(安装时一步过了 啥也没配置),操作时发现系统时间一直不对,于是安装了ntp跟阿里云等时钟源对过,发现一对时系统就变成了昨天,我把系统时间强制改为了现在,再次对时,时间又回退到昨天,最后发现时区选错了,选成了PST。解决方法cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime..._ntp对时 时区
文章浏览阅读6.3k次,点赞18次,收藏81次。1.需求分析1.1 输入数据建立二叉树,分别以前序、中序、后序的遍历方式显示输出二叉树的遍历结果。输入输出形式:124$$5$3$$preOrder1 2 4 5 3inOrder4 2 5 1 3afterOrder4 5 2 3 1功能:利用树存储数据,采用递归的方式做到先序、中序、后序三种遍历方式输出数据范围:0~9测试数据: 124$$5$3$$ ..._二叉树叶子节点实验
文章浏览阅读311次。题目描述n(n\le 100)n(n≤100)名同学参加歌唱比赛,并接受m(m\le 20)m(m≤20)名评委的评分,评分范围是 0 到 10 分。这名同学的得分就是这些评委给分中去掉一个最高分,去掉一个最低分,剩下m-2m−2个评分的平均数。请问得分最高的同学分数是多少?评分保留 2 位小数。输入格式无输出格式无输入输出样例输入 ..._【深基7.例4】歌唱比赛
文章浏览阅读1.1k次,点赞4次,收藏5次。在Vue中可非常便利地进行事件处理,例如:点击事件、鼠标悬停事件等。_vue html里面如何直接写事件函数
文章浏览阅读4.5k次,点赞15次,收藏67次。南京邮电大学离散数学实验一(求主析取和主合取范式)_离散数学实验
文章浏览阅读1.5w次,点赞2次,收藏5次。1.在springcloud中服务的 Instance ID 默认值是:${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}},也就是:主机名:应用名:应用端口。如图12.可以自定义:eureka.instance...._spring.cloud.client.ip-address