JAVA之NIO按行读取大文件
做项目过程中遇到要解析100多M的TXT文件,并入库。用之前的FileInputStream、BufferedReader显然不行了,虽然readLine这方法可以直接按行读取,但是去读一个140M左右,68W条数据的文件时,不但耗时长而且会内存溢出,即你等不到读完68W条数据时就内存溢出了。所以得用NIO下面的相关对象及方法。
用到 字节缓冲区(Java.nio.ByteBuffer);用于读取、写入、映射和操作文件的通道( java.nio.channels.FileChannel);设置文本字条集(java.nio.charset.Charset);支持对随机存取文件的读取和写入(java.io.RandomAccessFile)。
具体思路是:设置两个缓冲区,一大一小,大的缓冲区为每次读取的量,小的缓冲区存放每行的数据(确保大小可存放文本中最长的那行)。读取的时候判断是不是换行符13,是的话则返回一行数据,不是的话继续读取,直到读完文件。
实现方法:
FileChannel fc=raf.getChannel();
//一次读取文件,读取的字节缓存数
ByteBuffer fbb=ByteBuffer.allocate(1024*5);
fc.read(fbb);
fbb.flip();
//每行缓存的字节 根据你的实际需求
ByteBuffer bb=ByteBuffer.allocate(500);
//判断是否读完文件
public boolean hasNext() throws IOException {
if(EOF)return false;
if(fbb.position()==fbb.limit()){//判断当前位置是否到了缓冲区的限制
if(readByte()==0) return false;
}
while(true){
if(fbb.position()==fbb.limit()){
if(readByte()==0) break;
}
byte a=fbb.get();
if(a==13){
if(fbb.position()==fbb.limit()){
if(readByte()==0) break;
}
return true;
}else{
if (bb.position() < bb.limit()) {
bb.put(a);
}else {
if(readByte()==0) break;
}
}
}
return true;
}private int readByte() throws IOException{
//使缓冲区做好了重新读取已包含的数据的准备:它使限制保持不变,并将位置设置为零。
fbb.rewind();
//使缓冲区做好了新序列信道读取或相对 get 操作的准备:它将限制设置为当前位置,然后将该位置设置为零。
fbb.clear();
if(this.fc.read(fbb)==-1){
EOF=true;
return 0;
}else{
fbb.flip();
return fbb.position();
}
}public byte[] next(){
bb.flip();//此处很重要,返回byte数组方便,行被分割的情况下合并,否则如果正好达到缓冲区的限制时,一个中文汉字被拆了两个字节,就会显示不正常
byte tm[] = Arrays.copyOfRange(bb.array(), bb.position(), bb.limit());
bb.clear();
return tm;
}
JAVA之NIO按行读取大文件的更多相关文章
- JAVA之NIO按行读写大文件,完美解决中文乱码问题
;//一次读取的字节长度 File fin = new File("D:\\test\\20160622_627975.txt");//读取的文件 File fout = new ...
- Java多线程读取大文件
前言 今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍.好玩的地方比较远,近处又感觉没意思.于是乎,闲着写篇文章,总结下昨天写的程序吧. 昨天下午朋 ...
- NIO入门之轻松读取大文件
NIO入门之轻松读取大文件 今天同事碰到了一个问题,从游戏服务器下载下来的输出log有一个多G大.用记事本打不开,EditPlus也打不开,都提示文件太大.用word也打不开,提示文件大于512M.打 ...
- Java高效读取大文件
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...
- Java高效读取大文件(转)
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung(http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读 ...
- java 分次读取大文件的三种方法
1. java 读取大文件的困难 java 读取文件的一般操作是将文件数据全部读取到内存中,然后再对数据进行操作.例如 Path path = Paths.get("file path&qu ...
- Java读取大文件的高效率实现
1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...
- java读取 500M 以上文件,java读取大文件
java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...
- java 读取txt,java读取大文件
java 读取txt,java读取大文件 package com.bbcmart.util; import java.io.File;import java.io.RandomAccessFile;i ...
随机推荐
- MyEclipse注释配置
MyEclipse注释配置 配置路径 1.1. JAVA 打开MyEclipse,选择Window>Preferences>Java>Code Style>Code ...
- 【转载】浅谈Excel开发:一 Excel 开发概述
博客园就是好,想要什么都给总结了,多谢 原文转载:http://www.cnblogs.com/yangecnu/p/Excel-Develpment-Introduction.html 做Offic ...
- Digit(湘潭大学比赛)
题目链接: 点击打开链接 中文问题目就不解释了. 思路,找到这个数对应的的数字是多少,然后对这个数取对应的位置. 步骤:先打表打出一位数字对应字符串的长度,两位数的,到8,9就差不多了. 先确定给定的 ...
- SpringMVC上传多文件
springMVC实现 多文件上传的方式有两种,一种是我们经常使用的以字节流的方式进行文件上传,另外一种是使用springMVC包装好的解析器进行上传.这两种方式对于实 现多文件上传效率上却有着很大的 ...
- 区间DP中的环形DP
vijos1312 链接:www.vijos.org/p/1312 题目分析:经典的环形DP(区间DP) 环形DP,首先解环过程,把数组复制一遍,n个数变成2n个数,从而实现解环 dp[i][j]表示 ...
- nodejs 打造 多人对战游戏服务器(初级入门)
使用socket.set 和 socket.get 在存取玩家信息 百牛信息技术bainiu.ltd整理发布于博客园 socket.get('playerinfo', function (err, p ...
- label标签的可访问性
与表单元素关联的方法(IE6下label标签包裹控件的方法是不顶用的): 1 使用for和id关联控件 <p><label for="test">标签< ...
- centos7更改远程端口
centos7更改远程端口 一.创建个普通账户(useradd work),给普通账户创建密码(password work) 二.查看应有的软件是否安装 1.查看semanager是否安装执行下面命令 ...
- input required字段;django input输入框不填写会自动变红如何修改
前端页面中,input不输入任何内容时,点击submit时,未填写的input会标红框,有些人还会有"该字段必填的字样"!! 什么鬼,你妹的,js也见不到,css3动画也见不到,怎 ...
- mui 中在windows中打开新页面
<!doctype html><html> <head> <meta charset="utf-8"> <title>& ...