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 ...
随机推荐
- bzoj 2301 [HAOI2011]Problem b(莫比乌斯反演+分块优化)
题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 1≤n≤50000,1≤a≤b≤50000, ...
- ubuntu docker的安装和使用
Docker CE for Ubuntu Docker CE for Ubuntu is the best way to install the Docker platform on Ubuntu L ...
- C语言变量声明问题——变量定义一定要放在所有执行语句/语句块的最前面吗?
报错信息:error C2065: 'salary' : undeclared identifier #include <stdio.h> void main(){ printf(&quo ...
- 书写优雅的shell脚本(二)- `dirname $0`
在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".". 这个命令写在脚本文件里才有作用,他返回这个脚本文件放置的目录,并可以根据这个 ...
- 命令行 sql 将结果导出到文件
1. into outfile filename; Mysql查询结果导出为Excel的几种方法 mysql> use world; # 使用 mysql 自带的 world 数据库 mysql ...
- 创建Android本地repo
/**************************************************************************** * 创建Android本地repo * 说明 ...
- 【HDU 1754】 I Hate It
[题目链接] 点击打开链接 [算法] 树状数组的最值查询 详见这篇文章 : https://blog.csdn.net/u010598215/article/details/48206959 [代码] ...
- CS231n 2016 通关 第二章-KNN
课程内容全纪录: 1.讲解图像分类的难点 1.光照强度 2.主体变形 3.主体与背景咬合 4.主体与背景相接近 5.同类别间存在区别 2.KNN 1.最近邻算法 2.Knn 3.hyperpara ...
- Event Handling Guide for iOS--(二)---Gesture Recognizers
Gesture Recognizers 手势识别器 Gesture recognizers convert low-level event handling code into higher-leve ...
- k8s-StatefulSet控制器-十四
一.StatefulSet概述 RC.Deployment.DaemonSet都是面向无状态的服务,它们所管理的Pod的IP.名字,启停顺序等都是随机的,而StatefulSet管理所有有状态的服务, ...