Многопоточная обработка файла java

Русские Блоги

Прежде чем писать, объявите, что эта статья основана на примере многопоточного файла JAVA для чтения и записи, полученного на веб-сайте блогового сада. Я был в положении, когда писал свою собственную программу. Автор улучшил на основе написания, но не могу вспомнить исходный адрес. Если есть инсайдеры, напишите адрес, я процитирую или перепечатаю эту статью.

Эта программа основана на том, что на заднем плане системы существует файл журнала размером почти 2 ГБ. Вам будет трудно открыть его в любом редакторе. Для такой обработки анализа больших файлов решение состоит в том, чтобы использовать несколько потоков для разделения и чтения указанного большого файла. Получите информацию, которая нам нужна. Не так много, чтобы сказать, код включен, есть комментарии, чтобы помочь понять.

package com.thread.multipl.mysolution;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.CountDownLatch;

/**
* Этот поток используется для чтения файла. Когда получено указанное ключевое слово, добавьте 1 к указанному объекту.
* @author 2
*
*/
public class ReadThread extends Thread
// Определяем длину массива байтов (бамбуковая трубка для забора воды)
private final int BUFF_LEN = 256;
// Определяем начальную точку чтения
private long start;
// Определяем конечную точку чтения
private long end;
// прочитанные байты выводятся в raf. RandomAccessFile можно понимать как файловый поток, то есть указанная часть объекта упаковки извлекается из файла
private RandomAccessFile raf;
// Ключевые слова, которые необходимо указать в теме
private String keywords;
// Сколько раз эта тема читала ключевое слово
private int curCount = 0;
/**
* Класс, к которому начал присоединяться jdk1.5, является многопоточным вспомогательным классом.
* Используется для равномерного выполнения операций перед началом многопоточности или для вызова основного потока для выполнения соответствующих операций после завершения многопоточности.
*/
private CountDownLatch doneSignal;
public ReadThread(long start, long end, RandomAccessFile raf,String keywords,CountDownLatch doneSignal) this.start = start;
this.end = end;
this.raf = raf;
this.keywords = keywords;
this.doneSignal = doneSignal;
>

public void run() try raf.seek(start);
// Этот поток отвечает за чтение размера файла
long contentLen = end - start;
// Определите, что вам нужно прочитать не более нескольких раз, чтобы завершить чтение этой темы
long times = contentLen / BUFF_LEN+1;
System.out.println (this.toString () + "Количество необходимых чтений:" + раз);
byte[] buff = new byte[BUFF_LEN];
int hasRead = 0;
String result = null;
for (int i = 0; i < times; i++) <
// Прежде чем SEEK определит начальную позицию, прочитайте содержимое указанной длины группы байтов здесь, метод read возвращает следующую позицию, чтобы начать чтение
hasRead = raf.read(buff);
// Если количество прочитанных байтов меньше 0, выйдите из цикла! (До конца байтового массива)
if (hasRead < 0) <
break;
>
result = new String(buff,"gb2312");
/// System.out.println(result);
int count = this.getCountByKeywords(result, keywords);
if(count > 0) this.curCount += count;
>
>

KeyWordsCount kc = KeyWordsCount.getCountObject();

kc.addCount(this.curCount);

doneSignal.countDown();//current thread finished! noted by latch object!
> catch (IOException e) // TODO Auto-generated catch block
e.printStackTrace();
>
>

public long getStart() return start;
>

public void setStart(long start) this.start = start;
>

public long getEnd() return end;
>

public void setEnd(long end) this.end = end;
>

public RandomAccessFile getRaf() return raf;
>

public void setRaf(RandomAccessFile raf) this.raf = raf;
>

public int getCountByKeywords(String statement,String key) return statement.split(key).length-1;
>

public int getCurCount() return curCount;
>

public void setCurCount(int curCount) this.curCount = curCount;
>

public CountDownLatch getDoneSignal() return doneSignal;
>

public void setDoneSignal(CountDownLatch doneSignal) this.doneSignal = doneSignal;
>
>
package com.thread.multipl.mysolution;

import java.io.File;
import java.io.RandomAccessFile;
import java.util.concurrent.CountDownLatch;

public class MultiReadTest
/**
* Тест многопоточного чтения файла
* @param args
*/
public static void main(String[] args) // TODO Auto-generated method stub
final int DOWN_THREAD_NUM = 10; // Запуск 10 потоков для чтения указанного файла
final String OUT_FILE_NAME = "d: \\ Yi Tian Tu Long Ji.txt";
окончательные строковые ключевые слова = "Wuji";
//jdk1.5 вспомогательный класс потока, класс, используемый основным потоком для ожидания завершения всех дочерних потоков,
// Другое решение: напишите свой таймер, лично предложите использовать этот класс
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 ("Общая длина файла:" + длина + "байт");
// Количество байтов, которые должны быть прочитаны на поток
long numPerThred = length / DOWN_THREAD_NUM;
System.out.println ("Количество байтов, прочитанных каждым потоком:" + numPerThred + "bytes");
// остаток после деления всего файла
long left = length % DOWN_THREAD_NUM;
for (int i = 0; i < DOWN_THREAD_NUM; i++) <
// Открываем входной поток и объект RandomAccessFile для каждого потока,

// Пусть каждый поток отвечает за чтение разных частей файла
outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
if (i != 0) <
//
// isArr [i] = new FileInputStream ("d: / brave heart.rmvb");
// Создать несколько объектов RandomAccessFile с указанным выходным файлом

>
if (i == DOWN_THREAD_NUM - 1) <
// // последний поток читает указанный numPerThred + левые байты
// System.out.println («первый» поток + i + »считывает позицию из" + i * numPerThred + "в" + ((i + 1) * numPerThred + left) + "");
new ReadThread(i * numPerThred, (i + 1) * numPerThred
+ left, outArr[i],keywords,doneSignal).start();
> else <
// Каждый поток отвечает за чтение определенного количества байтов numPerThred
// System.out.println («первый» поток + i + »считывает позицию из" + i * numPerThred + "в" + ((i + 1) * numPerThred) + "");
new ReadThread(i * numPerThred, (i + 1) * numPerThred,
outArr[i],keywords,doneSignal).start();
>
>
>catch(Exception e) e.printStackTrace();
>
// finally//
// >
// Подтверждаем, что все задачи потока выполнены, и начинаем выполнение операции основного потока
try doneSignal.await();
> catch (InterruptedException e) // TODO Auto-generated catch block
e.printStackTrace();
>
// Здесь необходимо принять решение, все прочитанные рабочие потоки выполнены.
KeyWordsCount k = KeyWordsCount.getCountObject();
// Map resultMap = k.getMap();
System.out.println ("Количество вхождений указанного ключевого слова:" + k.getCount ());
>

>
package com.thread.multipl.mysolution;


/**
* Статистические ключевые объекты
* @author 2
*
*/

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 («Увеличьте количество раз:» + количество);
this.count += count;
>

public int getCount() return count;
>

public void setCount(int count) this.count = count;
>

>

Результаты приведены ниже:
[quote] Общая длина файла: 2012606 байт
Количество байтов, прочитанных каждым потоком: 201260 байтов
Тема [Тема-0,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема-1,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема-2,5, главная] Нужно прочитать количество раз: 787
Тема [Тема-3,5, главная] Нужно прочитать количество раз: 787
Тема [Тема-4,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема 5,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема 6,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема-7,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема 8,5, главная] Необходимо прочитать количество раз: 787
Тема [Тема-9,5, главная] Необходимо прочитать количество раз: 787
Увеличивает: 0
Увеличивает: 146
Увеличивает: 432
Увеличивает: 539
Увеличивает: 587
Увеличивает: 717
Увеличивает: 631
Увеличивает: 467
Увеличивает: 665
Увеличивает: 538
Количество вхождений указанного ключевого слова: 4722 [/ quote]

Читайте также:  Call JavaScript function on page load.

Я использовал 10 потоков, чтобы разобрать историю «И Тянь Ту Лонг Джи», написанную Мастером Цзинь Юном. Слово «Уцзи» появилось в этом романе 4472 раза. Я не мог найти файл большего размера. Размер Yi Tian Tu Long Ji.txt составляет 4 метра.

[b] О роли CountDownLatch: [/ b]
В документации API это объясняется как вспомогательный класс. Класс инструмента для управления переключением между основным потоком и дочерним потоком. Как искать в Интернете. Некоторые люди обсуждали это в ITEYE. Я использую его здесь для решения таких проблем: [b] Убедившись, что 10 потоков завершили работу по разбору файлов, система вызывает основной поток, чтобы выполнить оставшиеся действия, а именно: вывести «число вхождений». [/ b] Если это не обеспечено, это приведет к выполнению четвертого потока, последующий поток еще не запущен, и система сделала последний шаг для вывода статистических результатов, которые не достигнут желаемого эффекта. Здесь есть еще одно простое решение, напишите счетчик самостоятельно, от 10 до 1, 10 потоков. Это зависит от личных предпочтений.

Источник

Оцените статью