标签:blog http java 使用 os strong 文件 io
在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址。如果有知情者,烦请帖出地址,我在此文上加入引用或转载。
本程序是基于这么一种考虑,某系统后台有个将近2G大小的日志文件,你用任何编辑器去打开它,都将会很困难。针对这样的大文件解析处理,解决方案是使用多个线程,分割读取指定的大文件。获取我们所需要的信息。不多说,上代码了,有注释可以帮助理解。
- package com.thread.multipl.mysolution;
-
- import java.io.File;
- import java.io.RandomAccessFile;
- import java.util.concurrent.CountDownLatch;
-
- public class MultiReadTest {
-
-
- public static void main(String[] args) {
-
- final int DOWN_THREAD_NUM = 10;
- final String OUT_FILE_NAME = "d:\\倚天屠龙记.txt";
- final String keywords = "无忌";
-
-
- CountDownLatch doneSignal = new CountDownLatch(DOWN_THREAD_NUM);
- RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];
- try{
- long length = new File(OUT_FILE_NAME).length();
- System.out.println("文件总长度:"+length+"字节");
-
- long numPerThred = length / DOWN_THREAD_NUM;
- System.out.println("每个线程读取的字节数:"+numPerThred+"字节");
-
- long left = length % DOWN_THREAD_NUM;
- for (int i = 0; i < DOWN_THREAD_NUM; i++) {
-
-
-
- outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
- if (i != 0) {
-
-
- }
- if (i == DOWN_THREAD_NUM - 1) {
- new ReadThread(i * numPerThred, (i + 1) * numPerThred
- + left, outArr[i],keywords,doneSignal).start();
- } else {
-
- new ReadThread(i * numPerThred, (i + 1) * numPerThred,
- outArr[i],keywords,doneSignal).start();
- }
- }
- }catch(Exception e){
- e.printStackTrace();
- }
-
- try {
- doneSignal.await();
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- }
-
- KeyWordsCount k = KeyWordsCount.getCountObject();
- System.out.println("指定关键字出现的次数:"+k.getCount());
- }
-
- }
- package com.thread.multipl.mysolution;
-
-
-
- public class KeyWordsCount {
-
- private static KeyWordsCount kc;
-
- private int count = 0;
- private KeyWordsCount(){
-
- }
-
- public static synchronized KeyWordsCount getCountObject(){
- if(kc == null){
- kc = new KeyWordsCount();
- }
- return kc;
- }
-
- public synchronized void addCount(int count){
- System.out.println("增加次数:"+count);
- this.count += count;
- }
-
- public int getCount() {
- return count;
- }
-
- public void setCount(int count) {
- this.count = count;
- }
-
- }
运行结果如下:
引用
文件总长度:2012606字节
每个线程读取的字节数:201260字节
Thread[Thread-0,5,main] 需要读的次数:787
Thread[Thread-1,5,main] 需要读的次数:787
Thread[Thread-2,5,main] 需要读的次数:787
Thread[Thread-3,5,main] 需要读的次数:787
Thread[Thread-4,5,main] 需要读的次数:787
Thread[Thread-5,5,main] 需要读的次数:787
Thread[Thread-6,5,main] 需要读的次数:787
Thread[Thread-7,5,main] 需要读的次数:787
Thread[Thread-8,5,main] 需要读的次数:787
Thread[Thread-9,5,main] 需要读的次数:787
增加次数:0
增加次数:146
增加次数:432
增加次数:539
增加次数:587
增加次数:717
增加次数:631
增加次数:467
增加次数:665
增加次数:538
指定关键字出现的次数:4722
我用10个线程去解析金庸大师写的《倚天屠龙记》,“无忌”这个词在这部小说中一共出现了4722次。实在找不到再大一些的文件了。倚天屠龙记.txt的大小4M出头。
关于CountDownLatch类的作用说明:
在API文档中,已经说明是一个辅助类。用于控制主线程与子线程之间切换的一个工具类。用法网上去搜下。ITEYE里也有人讨论过。我在这里使用它解决这样的问题:在确保10个线程都完成文件的解析工作后,系统调用主线程做剩下该做的事情,即:输出“出现的次数”。不确保这点的话,会导致执行完第4个线程,后面的线程还没开始,系统已经做最后一步输出统计结果,这样就达不到我们要的效果。这里解决方案有另一个简单的,自己写个计数器,从10记到1,10个线程嘛。这个看个人喜好吧。
原文:http://babystudyjava.iteye.com/blog/1732814
JAVA多线程读写文件范例,布布扣,bubuko.com
JAVA多线程读写文件范例
标签:blog http java 使用 os strong 文件 io
原文地址:http://www.cnblogs.com/langtianya/p/3874019.html