做项目过程中遇到要解析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按行读取大文件的更多相关文章

  1. JAVA之NIO按行读写大文件,完美解决中文乱码问题

    ;//一次读取的字节长度 File fin = new File("D:\\test\\20160622_627975.txt");//读取的文件 File fout = new  ...

  2. Java多线程读取大文件

    前言 今天是五一假期第一天,按理应该是快乐玩耍的日子,但是作为一个北漂到京师的开发人员,实在难想出去那玩耍.好玩的地方比较远,近处又感觉没意思.于是乎,闲着写篇文章,总结下昨天写的程序吧. 昨天下午朋 ...

  3. NIO入门之轻松读取大文件

    NIO入门之轻松读取大文件 今天同事碰到了一个问题,从游戏服务器下载下来的输出log有一个多G大.用记事本打不开,EditPlus也打不开,都提示文件太大.用word也打不开,提示文件大于512M.打 ...

  4. Java高效读取大文件

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  5. Java高效读取大文件(转)

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung(http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 读 ...

  6. java 分次读取大文件的三种方法

    1. java 读取大文件的困难 java 读取文件的一般操作是将文件数据全部读取到内存中,然后再对数据进行操作.例如 Path path = Paths.get("file path&qu ...

  7. Java读取大文件的高效率实现

    1.概述 本教程将演示如何用Java高效地读取大文件.这篇文章是Baeldung (http://www.baeldung.com/) 上“Java——回归基础”系列教程的一部分. 2.在内存中读取 ...

  8. java读取 500M 以上文件,java读取大文件

    java 读取txt,java读取大文件 设置缓存大小BUFFER_SIZE ,Config.tempdatafile是文件地址 来源博客http://yijianfengvip.blog.163.c ...

  9. java 读取txt,java读取大文件

    java 读取txt,java读取大文件 package com.bbcmart.util; import java.io.File;import java.io.RandomAccessFile;i ...

随机推荐

  1. hdu 1541 Stars 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有 ...

  2. kafka 查询 SQL Query

    . SELECT COUNT(*) FROM wiseweb_crawler_foreignmedias WHERE site_id= AND (gathertime BETWEEN '2017-05 ...

  3. POJ-3352 Redundant Paths

    In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1..F) t ...

  4. VC++静态连接库

    目录 第1章静态连接库    1 1.1 同名函数的选择    1 1.2 模块合并    2 1.2.1 模块替换    4 1.3 内联函数    4 第1章静态连接库 静态连接库与动态连接库一样 ...

  5. BZOJ_2186_[Sdoi2008]沙拉公主的困惑_欧拉函数

    BZOJ_2186_[Sdoi2008]沙拉公主的困惑_欧拉函数 Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行 ...

  6. 「LuoguP1122」 最大子树和

    Description 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是 ...

  7. 泛型Class<T>和 T. <T>

    private T product; private Class<T> product; 这两个有什么区别呢,查了资料才知道,单独的T 代表一个类型 而 Class<T>代表这 ...

  8. E20170509-hm

    slice   vt. 切成片; 切下; 划分;  n. 薄片,切片 slicing  n. 切割; 限幅,限制; inspect    v. 视察; 检查 inspector  n. 检查员; (英 ...

  9. 51nod 1428【贪心】

    思路: 就是先排序,然后对每个取最小的结束时间. #include <bits/stdc++.h> using namespace std; typedef long long LL; c ...

  10. adb相关

    --------------------------------------------- adb logcat |find "nafio" >c:/logcat.txt 另 ...