文档章节

Java Nio 实现按行读取大文件(可执行)

性感小肚兜
 性感小肚兜
发布于 2016/08/30 18:20
字数 598
阅读 351
收藏 0

网上看到许多人发过类似的,发现多少都有点问题,自己花时间写了一份,加上了容错处理,大家可参考下。

注释什么的都有,有问题直接留言。代码日志需要log4j ,swingx 包,不想导出可删除相关代码。

匹配 macos,linux,window

/**
     * 使用nio 实现按行读取文件(大文件)
     *
     * @author Liuyang
     *
     * @param filepath
     *            文件路径
     * @param rbuffer
     *            每次缓冲字符区的大小
     * @param maxnumline
     *            最长行的字符个数
     * @return 每行数据的集合 发生异常返回null
     */
    public static List<String> readFileNioByLine(String filepath, ByteBuffer rbuffer, int maxnumline) {
        // 文件不存在或不是文件 返回null
        if (!new File(filepath).exists() || !new File(filepath).isFile()) {
            return null;
        }

            // 返回数据
        List<String> retStrList = new ArrayList<String>();
        try (FileInputStream fis = new FileInputStream(filepath);) {
            // 获取文件管道
            FileChannel fc = fis.getChannel();
            // 表示按行分割的标识   window:\r\n 13 10  linux/unix:\r  13 mac:\n 10
            byte changeLine = 10;
            if(OS.isLinux()){
                changeLine=13;
            }
            // 换行符前面字符组合,可解决乱码
            ByteBuffer elseBuffer = ByteBuffer.allocate(maxnumline * 3);
            // 将缓冲区中数据读到字符数组中
            byte[] bs = null;
            // 从管道中循环读取数据
            while (fc.read(rbuffer) != -1) {
                // 根据读取到的字节数确定即将获取的字节数组大小
                bs = new byte[rbuffer.position()];
                rbuffer.rewind();
                // 相对读,从position位置读取一个byte[]
                rbuffer.get(bs);
                // 清楚缓冲区,供下次使用
                rbuffer.clear();
                for (byte b : bs) {
                    // 遭遇换行符
                    if (b == changeLine) {
                        // 字符缓冲区位置,用于确定字节数组大小
                        int byteSize = elseBuffer.position();
                        // 确定出字节数组大小
                        byte[] byteLine = new byte[byteSize];
                        // position=0 准备读取数据
                        elseBuffer.rewind();
                        // 从position开始读取byteLine.length个字节
                        elseBuffer.get(byteLine);
                        // 如果是 剔除 /r 前的 /n 后转换为字符串
                        String line = new String(byteLine, 0, OS.isWindows()?byteLine.length - 1:byteLine.length);
                        //    添加到返回集合中
                        retStrList.add(line);
                        elseBuffer.clear();
                        continue;
                    }
                    try {
                        // 缓存住未匹配上的数据
                        elseBuffer.put(b);
                        //    由于提前确定的字节缓冲区太小导致错误
                    } catch (BufferOverflowException e) {
                        log.error("the maxNumLine is too small:"+e.getMessage());
                        return null;
                    }

                }
            }
            //    循环完毕,处理剩余数据,注释同上
            if (elseBuffer.position() > 0) {
                int byteSize = elseBuffer.position();
                byte[] byteLine = new byte[byteSize];
                elseBuffer.rewind();
                elseBuffer.get(byteLine);
                String line = new String(byteLine, 0, byteLine.length);
                retStrList.add(line);
                elseBuffer.clear();
            }
        } catch (FileNotFoundException e) {
            log.error("file not find:" + e.getMessage());
            return null;
        } catch (IOException e) {
            log.error("read file by line error:" + e.getMessage());
            return null;
        }
        return retStrList;
    }

© 著作权归作者所有

共有 人打赏支持
性感小肚兜
粉丝 0
博文 1
码字总数 598
作品 0
海淀
程序员
私信 提问
Java NIO AsynchronousFileChannel

原文链接 , 原文作者:Jakob Jenkov, 翻译:Neil Hao 在Java 7,AsynchronousFileChannel 被添加到了Java NIO中。使用AsynchronousFileChannel可以实现异步地读取和写入文件数据。 创建一个A...

Neil_Hao
2018/01/20
0
0
Java画蒙娜丽莎的微笑(记录)

最近在代码共享里共享了一份Java画蒙娜丽莎的微笑的源代码和资源文件,有人问我是怎么做的,这里简单说一下原理吧,很简单的,高手飘过吧~~。 一份是普通按行读取 一份是使用NIO读取 步骤: ...

山东-小木
2012/12/21
0
25
Java NIO:IO与NIO的区别

一、概念 NIO即New IO,这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标...

老菜鸟0217
01/06
0
2
Java NIO系列教程(十二) Java NIO与IO

原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html 作者:Jakob Jenkov 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我...

_夏天的风_
2013/07/11
0
0
java中使用多线程不能明显提高程序效率的一些原因.

java中使用多线程不能明显提高程序效率的一些原因. 使用多个线程来处理多任务的时候,效率肯定是有提高的.但是必须要慎用,否则容易出现问题. 1.多线程主要是为了充分利用多核cpu,大内存这些资...

Zhao-Qian
2012/08/15
0
2

没有更多内容

加载失败,请刷新页面

加载更多

Confluence 6 升级中的一些常见问题

升级的时候遇到了问题了吗? 如果你想尝试重新进行升级的话,你需要首先重新恢复老的备份。不要尝试再次对 Confluence 进行升级或者在升级失败后重新启动老的 Confluence。 在升级过程中的一...

honeymoose
今天
2
0
C++随笔(四)Nuget打包

首先把自己编译好的包全部准备到一个文件夹 像这样 接下来新建一个文本文档,后缀名叫.nuspec 填写内容 <?xml version="1.0"?><package xmlns="http://schemas.microsoft.com/packaging/201......

Pulsar-V
今天
2
0
再谈使用开源软件搭建数据分析平台

三年前,我写了这篇博客使用开源软件快速搭建数据分析平台, 当时收到了许多的反馈,有50个点赞和300+的收藏。到现在我还能收到一些关于dataplay2的问题。在过去的三年,开源社区和新技术的发...

naughty
今天
3
0
Python3的日期和时间

python 中处理日期时间数据通常使用datetime和time库 因为这两个库中的一些功能有些重复,所以,首先我们来比较一下这两个库的区别,这可以帮助我们在适当的情况下时候合适的库。 在Python文...

编程老陆
今天
2
0
分布式面试整理

并发和并行 并行是两个任务同时进行,而并发呢,则是一会做一个任务一会又切换做另一个任务。 临界区 临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用,但是每一次,只能有...

群星纪元
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部