Java 多线程处理大文本文件

Wesley13
• 阅读 529

对于文本文件,大部分都是一个线程处理一个文件,如果文本文件比较大,没找到类似如果多线程处理一个文本文件的方式。针对大文件的处理,写入如下代码,感觉不是太好,希望大神们指正。

package net.dotool.demo;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import net.dotool.IoTools;

public class BigFileDealMain {
    static ExecutorService pool = Executors.newFixedThreadPool(2);
    static CountDownLatch count = new CountDownLatch(2);

    public static void main(String[] args) {
        FileChannel fc = null;
        try {
            fc = new RandomAccessFile("F:\\logs\\server.log.2018-06-07-14", "r").getChannel();
            long t = System.currentTimeMillis();
            for (int i = 0; i < 2; i++) {
                pool.execute(new ReadThread(fc));
            }
            count.await();
            pool.shutdown();
            System.out.println(System.currentTimeMillis() - t);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IoTools.close(fc);
        }
    }

    public static synchronized ByteBuffer read(FileChannel fc) {
        ByteBuffer bb = ByteBuffer.allocate(4096);
        try {
            if (fc.position() >= fc.size())
                return null;
            fc.read(bb);
            bb.flip();
            long filePosition = fc.position();
            int lastN = 0;
            int nowLimit = bb.limit();
            for (int p = nowLimit - 1; p > 0; p--) {
                bb.position(p);
                if ('\n' == bb.get()) {
                    lastN = p + 1;
                    break;
                }
            }
            bb.position(0);
            bb.limit(lastN);
            if (lastN > 0)
                fc.position(filePosition - (nowLimit - lastN));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bb;
    }

    public static class ReadThread implements Runnable {
        FileChannel fc;

        public ReadThread(FileChannel fc) {
            this.fc = fc;
        }

        @Override
        public void run() {
            ByteBuffer bb = null;
            while ((bb = read(fc)) != null) {
                int lastP = 0;
                while (bb.hasRemaining()) {
                    if ('\n' == bb.get()) {
                        int nowP = bb.position();
                        bb.position((int) lastP);
                        int len = nowP - lastP;
                        byte[] b1 = new byte[len > 2 ? len - 2 : len];
                        bb.get(b1);
                        lastP = nowP;
                        if (len > 2) {//最后一两个字节是\r\n ,不同的系统可能换行符不同,
                            bb.get();
                            bb.get();
                        }
                        String str = new String(b1, Charset.forName("gbk"));
                        System.out.println(str);
                    }
                }
            }
            count.countDown();
        }
    }
}
点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
SHELL编程四剑客之Sed工具
SED是一个非交互式文本编辑器,它可对文本文件和标准输入进行编辑,标准输入可以来自键盘输入、文本重定向、字符串、变量,甚至来自于管道的文本。Sed工具在处理文本时默认把当前处理的行存储在临时缓冲区中,称为“模式空间”(patternspace)。如果要将变化写入磁盘、文件需要使用i参数。sed命令语法参数格式:sed参数‘sed内置命令字符‘
Wesley13 Wesley13
3年前
Java文件格式
\.java文件是保存源代码的文本文件(\代表类名)使用javac\.java可以编译该文件使用java\可以运行该类\.class是用于保存Java类的二进制编码以及Class对象,每一个Java类都有一个解释该类特征的Class对象。\.jar文件是一种压缩文件格式打包命令jarcvf
Stella981 Stella981
3年前
35个你也许不知道的Google开源项目
Google是支持开源运动的最大公司之一,它们现在总共发布有超过500个的开源项目(大部分都是利用它们的API来完成),本文将列举一些有趣的开源项目,其中很可能有不少你不知道的哦。文本文件处理:GoogleCRUSH(CustomReportingUtilitiesforSHell)CRUSH是为命令行
Wesley13 Wesley13
3年前
Java高级特性 第4节 输入输出流
一、使用I/O操作文件  关键步骤:使用File类操作文件或目录属性使用FileInputStream类读文本文件使用FileOutputStram类写文本文件使用BufferedReader类和FileReader类读文本文件使用BufferedWriter类和
Stella981 Stella981
3年前
Lucene 架构 总结
Lucene总的来说是:一个高效的,可扩展的,全文检索库。全部用Java实现,无须配置。仅支持纯文本文件的索引(Indexing)和搜索(Search)。不负责由其他格式的文件抽取纯文本文件,或从网络中抓取文件的过程。在Luceneinaction中,Luce
Wesley13 Wesley13
3年前
Java线程与多线程
1线程与多线程1.1线程是什么?线程(Thread)是一个对象(Object)。用来干什么?Java线程(也称JVM线程)是Java进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。Java程序采用多线程方式来支持大量的并发请求处理,程序如果在
Wesley13 Wesley13
3年前
Java 并发编程:AQS 的互斥锁与共享锁
我们知道现代机器处理器几乎都是多核多线程的,引入多核多线程机制是为了尽可能提升机器整体处理性能。但是多核多线程也会带来很多并发问题,其中很重要的一个问题是数据竞争,数据竞争即多个线程同时访问共享数据而导致了数据冲突(不正确)。数据竞争如果没处理好则意味着整个业务逻辑可能出错,所以在高并发环境中我们要特别注意这点。!(https://pic2.zhim
Stella981 Stella981
3年前
Python之文件处理
Python之文件处理不同模式打开文件的完全列表:模式描述r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。r打开一个文件用于读写。文件指针将会放在文件的开头。r
流浪剑客 流浪剑客
1年前
BBEdit 注册密钥激活 + 完整安装激活教程 支持M1
是一款功能强大的文本编辑器,专为Mac用户设计。它提供了一系列强大的工具和功能,帮助用户处理和编辑各种文本文件,适用于开发者、写作者和普通用户。BBEdit拥有简洁而直观的界面,让用户可以轻松地打开、编辑和保存各种文本文件。它支持多种编码格式,包括ASCI