Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.shashok.vpustotu;
- import java.awt.event.*;
- import java.io.*;
- import java.nio.charset.Charset;
- import java.nio.file.*;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.util.*;
- import java.util.concurrent.*;
- import javax.swing.Timer;
- //кодирование в Hex формат
- import org.apache.commons.codec.binary.Hex;
- //парсинг html
- import org.jsoup.Jsoup;
- import org.jsoup.nodes.*;
- //парсинг командной строки
- import com.beust.jcommander.*;
- import static java.nio.file.StandardOpenOption.*;
- public class Grabber implements Runnable{
- static BlockingQueue<String> queue = new ArrayBlockingQueue<>(10); //очередь цитат от парсеров в обработчик
- static Set<String> hashes = new HashSet<>(); //список хешей прочтёных цитат
- static int quotesCount, dupCount; //счетчики цитат и дубликатов
- @Override
- public void run() {
- try {
- while (true) { //в вечном цикле собираем данные
- Document doc = Jsoup.connect("http://vpustotu.ru/moderation/").get();
- Element element = doc.getElementsByClass("fi_text").first();
- if (element != null){
- queue.put(element.text()); //и отправляем их в очередь
- }
- }
- } catch (IOException | InterruptedException e) {
- e.printStackTrace();
- }
- }
- private static class CommandLine {
- @Parameter(names = "-h", help = true)
- boolean help;
- @Parameter(names = "-w", description = "количество потоков")
- int workers = 2;
- @Parameter(names = "-r", description = "частота отчетов (сек)")
- int reportPeriod = 10;
- @Parameter(names = "-d", description = "кол-во дубликатов для остановки")
- int dupToStop = 500;
- @Parameter(names = "-hf", description = "файл хешей")
- String hashFile = "hash.bin";
- @Parameter(names = "-qf", description = "файл записей")
- String quotesFile = "quotes.txt";
- }
- public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InterruptedException {
- final CommandLine commandLine = new CommandLine(); //тут будут переданные аргументы
- JCommander commander = new JCommander(commandLine, args); //вот такой нетипичный вызов
- if (commandLine.help) commander.usage(); //вызов справки надо обрабатывать вручную
- MessageDigest md5 = MessageDigest.getInstance("MD5");
- //Открываем файлы: хеши на чтение и запись, цитаты только на запись
- try (OutputStream hashFile = Files.newOutputStream(Paths.get(commandLine.hashFile),
- CREATE, APPEND, WRITE, SYNC);
- InputStream hashStream = Files.newInputStream(Paths.get(commandLine.hashFile));
- BufferedWriter quotesFile = Files.newBufferedWriter(Paths.get(commandLine.quotesFile),
- Charset.forName("UTF8"), CREATE, APPEND, WRITE, SYNC)) {
- //читаем хеши
- byte[] hbytes = new byte[16]; //читать будем блоками по 16 байт - как раз один хеш
- while (hashStream.read(hbytes) != -1){
- hashes.add(Hex.encodeHexString(hbytes));
- }
- //в цикле создадим нужное нам количество worker'oв
- for (int i = 0; i < commandLine.workers; i++){
- Thread worker = new Thread(new Grabber());
- worker.setPriority(2);
- worker.setDaemon(true);
- worker.start();
- }
- //таймер оповещения о текущем состоянии
- new Timer(commandLine.reportPeriod * 1000, new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent arg0) {
- System.out.printf("Всего %d / Повторов %d (%d записей/сек) \n",
- hashes.size(), dupCount, quotesCount/commandLine.reportPeriod);
- quotesCount = 0;
- }
- }).start();
- //оповещение при закрытии
- Runtime.getRuntime().addShutdownHook(new Thread() {
- public void run() {
- System.out.printf("Завершаю работу. Всего записей: " + hashes.size());
- }
- });
- while (true) {
- String quote = queue.take(); //принимаем цитаты по очереди
- quotesCount++;
- md5.update(quote.getBytes());
- byte[] hash = md5.digest(); //считаем хеш
- String hashString = Hex.encodeHexString(hash); //конвертируем в строку
- if (!hashes.contains(hashString)){ //проверяем уникальность хеша цитаты
- //все в порядке - заносим хеш в хранилище
- hashes.add(hashString);
- //записываем хеш и цитату в файлы
- hashFile.write(hash);
- quotesFile.write(quote);
- quotesFile.write("\n\n\n");
- quotesFile.flush();
- } else {
- if (++dupCount == commandLine.dupToStop){
- System.out.println("Достигнут предел повторов, завершаю работу. Всего записей: "+hashes.size());
- return;
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement