Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Средство для обеспечения повторов


Автор: sol78 28.8.2007, 18:38
Вот такая история - мне нужно что то для обеспечения проверки содержимого текучещей папки, т.е. не изменилось ли оно, через некоторое количество времени. Где то слышала что в джаве есть инструменты для этого, помогите найти и научите ими пользоваться?!
Заранее благодарна!

Автор: nornad 28.8.2007, 21:47
Цитата(sol78 @  28.8.2007,  21:38 Найти цитируемый пост)
Средство для обеспечения повторов

Повторов чего?

Цитата(sol78 @  28.8.2007,  21:38 Найти цитируемый пост)
Вот такая история - мне нужно что то для обеспечения проверки содержимого текучещей папки, т.е. не изменилось ли оно, через некоторое количество времени

Что здесь понимается под содержимым? Список файлов в папке? Некоторый файл в папке, содержащий какую-то информацию, которая может быть кем-то изменена?

Автор: sol78 28.8.2007, 21:53
Я пишу HotFolder  рабочей единицей тут является файл содержащейся в папке.
Дело в том что можно добовлять файлы runtime .Как мне отследить изменения, появился ли новый файл?

Автор: _Michael 28.8.2007, 21:57
Код

        File f = new File("C:/Windows/Fonts");
        String[] files = null;
        if(f.isDirectory()) {
            files = f.list();
            for(int i = 0; i<files.length; i++) {
                System.out.println(files[i]);
            }
        }
        List<String> fileList = Arrays.asList(files);
        Set oldFilesSet = new HashSet<String>();
        oldFilesSet.addAll(fileList);
        
//        Че то делаем или за нас делается

        files = f.list();
        fileList = Arrays.asList(files);
        Set newFilesSet = new HashSet<String>();
        newFilesSet.addAll(fileList);
        if(oldFilesSet.containsAll(newFilesSet) && 
                newFilesSet.containsAll(oldFilesSet))
        System.out.println("No changes");
        else
            System.out.println("There were changes in directory "+f.getAbsolutePath());
        
 Думаю ты етого хотела smile 

Автор: _Michael 28.8.2007, 22:14
sol78, ну че там? если что непонятно то говори smile

Автор: sol78 17.11.2007, 01:28
да что то тут много не понятно....

Автор: Kangaroo 17.11.2007, 01:45
Цитата(sol78 @  17.11.2007,  00:28 Найти цитируемый пост)
да что то тут много не понятно.... 

так не понятно, что 3 месяца разбирался?  smile 
напиши хоть, что не получается, попробуем помочь.

Автор: sol78 25.11.2007, 16:02
дело в том что задача не была четко поставлена так...

Как бы это профессиональнее реализовать?
-Есть система, которая должна с каким то периодом времени проверять состояние физ. папки 
  если состояние изменилось - обработать только новое.
 
Тут возникает проблема -нужно как то помнить прежние состояния папки, что бы избежать повторов?
Как определить, что состояние изменилось?

И  что есть в джабе для этого?    

Автор: LSD 25.11.2007, 17:12
http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html

Автор: sol78 26.11.2007, 14:28
Использование  Swing Timera:
как я поняла созадан  для swing/awt  компоненов, т.к использует механизм с листенерами
и для выполнения длительных задач все еще нужен отдельний сред...Но в принципе идея не плохая!

Может кто реально реализовывал выше изложенную задачу, помогите плизз?
   

Автор: LSD 28.11.2007, 00:21
Код

  private String path = ".\\res";
  private Timer timer = new Timer(1000, this);
  private Map<File, Long> files = new java.util.HashMap<File, Long>();

  public void start()
  {
    File file = new File(path);
    for(File f : file.listFiles())
    {
      files.put(f, f.lastModified());
    }
    timer.start();
  }

  public void actionPerformed(ActionEvent e)
  {
    File file = new File(path);
    File[] files = file.listFiles();
    if(files.length != this.files.size())
    {
      System.out.println("Files was added or removed");
    }
    else
    {
      for(File f : files)
      {
        Long l = this.files.get(f);
        if(l == null || l != f.lastModified())
        {
          System.out.println("File " + f + " changed");
        }
      }
    }
  }

Автор: sol78 19.12.2007, 21:32
Voznikla problema s rabotoy Timera
...Nuzhno dozhdat'sya rezultata raboti threda,
Код


import javax.swing.Timer;
import java.awt.event.*;
import ManageMonitor.*;

public class FolderAnalizator implements ActionListener, Runnable,ResultListener {
    private Task task;
    private Folder curFolder;
    private Timer timer;
    private CQueue queue;


    public FolderAnalizator(Folder folder) {
        curFolder = folder;
        queue = CQueue.getTaskQueue();
        task = new Task(folder);
        task.addMyEventListener(this);
        timer = new Timer((int) folder.getTestingTime(), this);
        
        new Thread(this).start();

    }

    public void actionPerformed(ActionEvent e) {

        if (!curFolder.getStateAction()) {
            timer.setRepeats(false);}
       else...
       // dolzhen vipolnyatsya , proizoydet event ProcessingResult(ResultEvent e) ;
    }

    public void run() {
        timer.setInitialDelay(0);
        timer.setLogTimers(true);
        timer.start();

    }
    public void ProcessingResult(ResultEvent e) {
               queue.putTask(task);
     
    }

Kak pri obrabotke odnogo eventa, dozhdat'sya drugogo, prichem vsya rabota idet v threde???

Автор: LSD 20.12.2007, 12:42
1. Не пиши транслитом, очень тяжело читать. Если нет русской клавиатуры используй чекбокс трансдит.

2. Объясни задачу почетче, из твоего кода ничего непонятно.
Например зачем этот код
Код

timer.setInitialDelay(0);
timer.setLogTimers(true);
timer.start();

выносить в отдельный поток? Он же выполняется очень быстро.

Автор: sol78 20.12.2007, 19:46
 smile translit ne rabotaet.....

Автор: sol78 20.12.2007, 20:14
Postorayusь obьyasnitь v chem problema:
est' nekiy main-thread(GUI), cherez nego zapuskaet Analizator, kotoriy rabotaet kak timer...
....Analizator delaet svoyu rabotu, gotovit Task i kladet ego v ConcurrentQueue . Dalee rabotaet ThreadPoolExecutor,
    zabiraet iz Q taski i vipolnyaya ix. Posle vipolneniya taska, resultat "vibrasivaetsya" kak event, Analizator slushaet eti sobitiya i reagiruet.
    I tak po krugu. 

....User sam mozhet zapustit' analizator i ostanovit' ego esli nuzhno

Tut voznikaet neskol'ko problem:
1.Kogda user zapuskat Analizator (new Analizator  ->run thread)
   ostanavlivaet ego (timer.setRepeats(false);)
   i snova zapuskaet Analizator (resultatom etogo imeem uzhe 2 threada)
kak bit'?
2 Kak vse eto delo krasivo ostanovit' (exit from app), pri uslovii chto nuzhno dozhdat'sya vipolneniya vsex zapuschenix iz  ThreadPoolExecutor???
Prilagayu ves' kod:
Analizator
Код

package MultyTh;

import javax.swing.Timer;
import java.awt.event.*;
import ManageMonitor.*;

public class FolderAnalizator implements ActionListener, Runnable,ResultListener {
    private Task task;
    private Folder curFolder;
    private Timer timer;
    private CQueue queue;


    public FolderAnalizator(Folder folder) {
        curFolder = folder;
        queue = CQueue.getTaskQueue();
        task = new Task(folder);
        Task.addMyEventListener(this);
        timer = new Timer((int) folder.getTestingTime(), this);
        System.out.println(folder.getTestingTime());// for debug
        new Thread(this).start();

    }

    public void actionPerformed(ActionEvent e) {
       
        
        if (!curFolder.getStateAction()) {
            timer.setRepeats(false);
        } 
     
            timer.stop();
            queue.putTask(task);
             
       
    }

    public void run() {
        timer.setInitialDelay(0);
        timer.start();

    }
    public void ProcessingResult(ResultEvent e) {
       
        if (e.getSource().equals(curFolder)) {
             System.out.println("Result Event"+ ((Folder)e.getSource()).getPath());
            if (e.getStateResult().getLastActionResult()) {
                timer.restart();
            } else
                timer.setRepeats(false);
        }
    }   

}


Queue
Код

package MultyTh;

import java.util.concurrent.*;

public class CQueue implements Runnable{
    private static final int MAX_QUEUE_SIZE = 10;
    private static CQueue queue = null;
    private BlockingQueue<Runnable> tasksQueue;
    private ThreadPoolExecutor threadPool;
    private CQueue() {
        tasksQueue = new ArrayBlockingQueue<Runnable>(MAX_QUEUE_SIZE);
        threadPool = new ThreadPoolExecutor(10, 20, 10, TimeUnit.SECONDS,
                                            new LinkedBlockingQueue<Runnable>());
       new Thread(this).start();

    }

    public static CQueue getTaskQueue() {
        if (queue == null) {
            queue = new CQueue();
        }
        return queue;
    }

    public void putTask(Runnable Task) {
        try {
            tasksQueue.put(Task);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    public void start() {
        try {
            Runnable t = tasksQueue.take();
            if (t != null) {
                System.out.println("Task exec");
                threadPool.execute(t);
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

    }

    public void run() {
       
        while(true){
            start();
        }
    }
}


Task
Код

package MultyTh;

import ManageMonitor.*;
import java.io.*;
import Plugins.*;
import javax.swing.event.EventListenerList;

public class Task implements Runnable {
    private static EventListenerList listenerList = new EventListenerList();
    private Folder srcFolder;

    public Task(Folder folder){
       srcFolder=folder;
    }
    public void run() {
        StateResult res;
        System.out.println("Task is working");
        res=srcFolder.getAction().myAction(srcFolder);
        fireMyEvent(new ResultEvent(srcFolder, res));
        
    }
    
    public static void addMyEventListener(ResultListener listener) {
           listenerList.add(ResultListener.class, listener);
       }

      
     public static void removeMyEventListener(ResultListener listener) {
           listenerList.remove(ResultListener.class, listener);
       }

      public static void fireMyEvent(ResultEvent evt) {
           Object[] listeners = listenerList.getListenerList();
               for (int i=0; i<listeners.length; i+=2) {
               if (listeners[i]==ResultListener.class) {
                   ((ResultListener)listeners[i+1]).ProcessingResult(evt);
               }
           }
       }

}


Автор: Zlatogorov 21.12.2007, 00:11
А может не стоит так усложнять себе жизнь.
Для таймеров есть http://www.opensymphony.com/quartz/ .
Прописывается временной паттерн и создаётся scheduling, и всё, остальное он берёт на себя.
К примеру :
"0 0/5 14 * * ?"     Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day 
Так что настройки очень гибкие. Сделал на нём Hotfolder - всё работает как часы.

Автор: LSD 21.12.2007, 12:27
Т.е. я так понял основная проблема состоит в том, что анализатор при остановке должен дождаться пока выполняться все таски положенные в очередь executor-а?
Так?

Автор: sol78 21.12.2007, 20:12
da, vernee poslednego i edinstvennogo (poka)

Автор: LSD 22.12.2007, 14:47
Вот примерный код как реализовать CQueue
Код

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

public class TaskTest
{
  public static void main(String[] args) throws Exception
  {
    CQueue taskQueue = CQueue.getTaskQueue();
    taskQueue.startProcessing();
    for(int i = 0; i < 50; i++)
      taskQueue.addTask(new DelayTask((long) (Math.random() * 10000)));
    taskQueue.stopAndWait();
    System.out.println("Task queue stopped");
  }
}

class CQueue implements Runnable
{
  private static final int MAX_QUEUE_SIZE = 10;
  private static CQueue queue = null;
  private BlockingQueue<Runnable> tasksQueue;
  private ThreadPoolExecutor threadPool;
  private AtomicBoolean running = new AtomicBoolean(false);
  private Thread workingThread;

  private CQueue()
  {
  }

  public static CQueue getTaskQueue()
  {
    if(queue == null)
    {
      queue = new CQueue();
    }
    return queue;
  }

  public void addTask(Runnable task)
  {
    if(!running.get())
      throw new IllegalStateException("Processor is not running");
    try
    {
      tasksQueue.put(task);
    }
    catch(InterruptedException ex)
    {
      ex.printStackTrace();
    }
  }

  public void startProcessing()
  {
    if(workingThread != null && workingThread.isAlive())
      return;
    tasksQueue = new ArrayBlockingQueue<Runnable>(MAX_QUEUE_SIZE);
    threadPool = new ThreadPoolExecutor(10, 20, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
    running.set(true);
    workingThread = new Thread(this, "CQueueWorkingThread");
    workingThread.start();
  }

  public void stopProcessing()
  {
    running.set(false);
  }

  public void join() throws InterruptedException
  {
    if(workingThread != null)
      workingThread.join();
  }

  public void stopAndWait() throws InterruptedException
  {
    stopProcessing();
    join();
  }

  public void run()
  {
    while(running.get() || !tasksQueue.isEmpty())
    {
      try
      {
        Runnable t = tasksQueue.poll(10, TimeUnit.MILLISECONDS);
        if(t != null)
        {
          System.out.println("Task " + t + " exec");
          threadPool.execute(t);
        }
      }
      catch(InterruptedException ex)
      {
      }
    }
    cleanup();
  }

  private void cleanup()
  {
    threadPool.shutdown();
    while(threadPool.getActiveCount() > 0)
    {
      try
      {
        Thread.sleep(10);
      }
      catch(InterruptedException e)
      {
      }
    }
    threadPool = null;
    tasksQueue = null;
    workingThread = null;
  }
}

class DelayTask implements Runnable
{
  private long timeout;

  public DelayTask(long timeout)
  {
    this.timeout = timeout;
  }

  public void run()
  {
    try
    {
      Thread.sleep(timeout);
    }
    catch(InterruptedException e)
    {
      e.printStackTrace();
    }
    System.out.println("DelayTask finished");
  }

  @Override
  public String toString()
  {
    return "DelayTask[" + timeout + "]";
  }
}


Там есть еще один момент, я не знаю что ты хотела реализовать на самом деле, но ограничение максимального размера tasksQueue на самом деле достаточно бесмысленно. Т.к. таски из нее в ThreadPoolExecutor перекидываются достаточно быстро и они никогда не заполняется.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)