2013-12-13 6 views
1

Трудно дать хороший заголовок моей проблеме, но это так. Сначала я делаю это на окнах, и его можно использовать и в ящике linux, поэтому мне нужно, чтобы исправление работало в обеих системах. Я отслеживаю каталог для новых файлов. Я в основном просматриваю файлы каталога и сравниваю их снова и снова и обрабатываю только новые файлы. Проблема в том, что я продолжаю получать сообщение об ошибке, когда файл не заканчивается, когда я пытаюсь обработать файл.Как проверить, закончен ли файл, прежде чем пытаться его обработать?

public class LiveDetectionsProvider extends DetectionsProvider { 
protected LiveDetectionsProvider.MonitorDirectory monitorDirectory = null; 
protected TimeModel timeModel = null; 
private ArrayList<String> loaded = new ArrayList(); 
private File topLayerFolder = null; 
public LiveDetectionsProvider(String directory, String id) { 
    super(directory, id); 
    timeModel = super.timeModel; 
} 
/** 
* Initialize the data provider. 
*/ 
public void initialize() { 
    try { 
     topLayerFolder = new File(directory); 
     File[] dir = topLayerFolder.listFiles(); 
     for (File file : dir) { 
      loaded.add(file.getName()); 
     } 
     monitorDirectory = new MonitorDirectory(); 
     monitorDirectory.execute(); 
    } 
    catch (Exception ex) { 
     Logger.getLogger(LiveDetectionsProvider.class.getName()).log(Level.SEVERE, "Failed to read detection\n{0}", ex.getMessage()); 
    } 
    super.initialize(); 
} 
/** 
* Un-initialize the data provider. 
*/ 
public void uninitialize() { 
    super.uninitialize(); 
    if (monitorDirectory != null) { 
     monitorDirectory.continuing = false; 
    } 
} 
/** 
* The class that is used to load the detection points in a background 
* thread. 
*/ 
protected class MonitorDirectory extends SwingWorker<Void, Void> { 
    public boolean continuing = true; 
    /** 
    * The executor service thread pool. 
    */ 
    private ExecutorService executor = null; 
    /** 
    * The completion service that reports the completed threads. 
    */ 
    private CompletionService<Object> completionService = null; 
    @Override 
    protected Void doInBackground() throws Exception { 
     int count = 0; 
     executor = Executors.newFixedThreadPool(1); 
     completionService = new ExecutorCompletionService<>(executor); 
     while (continuing && topLayerFolder != null) { 
      File[] dir = topLayerFolder.listFiles(); 
      Thread.sleep(10); 
      ArrayList<File> filesToLoad = new ArrayList(); 
      for (File file : dir) { 
       if (!loaded.contains(file.getName())) { 
        long filesize = 0; 
        boolean cont = true; 
        while (cont) { 
         if (file.length() == filesize) { 
          cont = false; 
          Thread.sleep(3); 
          filesToLoad.add(file); 
         } 
         else { 
          filesize = file.length(); 
          Thread.sleep(3); 
         } 
        } 
        Thread.sleep(3); 
       } 
      } 
      for (File file : filesToLoad) { 
       timeModel.setLoadingData(LiveDetectionsProvider.this.hashCode(), true); 
       completionService.submit(Executors.callable(new ReadDetection(file, false))); 
       while (completionService.take() == null) { 
        Thread.sleep(2); 
       } 
       loaded.add(file.getName()); 
       count++; 
       Logger.getLogger(LiveDetectionsProvider.class.getName()).log(Level.SEVERE, "Detection Message Count:" + count); 
      } 
      detectionsModel.fireStateChanged(DetectionsModel.CHANGE_EVENT_DETECTIONS); 
      timeModel.setLoadingData(LiveDetectionsProvider.this.hashCode(), false); 
     } 
     return null; 
    } 
} 
} 

Файл обрабатывается в соответствии с

completionService.submit(Executors.callable(new ReadDetection(file, false))); 

файл в данный момент все еще hasnt закончил быть написана и, таким образом, терпит неудачу. Я пробовал спящий мой поток, чтобы замедлить его, и я попытался проверить размер файла, который не изменился. Мой тестовый пример: я разархивирую tar-файл, содержащий тысячи файлов размером 1000 КБ.

+0

Пожалуйста, не забудьте добавить '?' на вопросы! Некоторые люди выполняют поиск на странице «?» и если ни один из них не существует в «вопросе», переходите непосредственно к следующему (фактическому) вопросу в очереди. –

+0

Есть ли способ изменить заголовок, чтобы добавить? к нему? – Jeremy

+0

Несомненно. Посмотрите на часть страницы между тегами вопроса и вашей подписью! Должно быть несколько ссылок, одним из которых является «редактировать». –

ответ

-1

Сначала да, это компиляция, посмотрите решение, которое я разместил по отношению к коду. В моем вопросе. Вы подменять

For(File file: dir){ 
while(!file.renameTo(file)){ 
Thread.sleep(1) 
} 
// In my code I check to see if the file name is already in the list which 
// contains files that have been previously loaded if its not I add it to a list 
// of files to be processed 
} 

в течение

 for (File file : dir) { 
      if (!loaded.contains(file.getName())) { 
       long filesize = 0; 
       boolean cont = true; 
       while (cont) { 
        if (file.length() == filesize) { 
         cont = false; 
         Thread.sleep(3); 
         filesToLoad.add(file); 
        } 
        else { 
         filesize = file.length(); 
         Thread.sleep(3); 
        } 
       } 
       Thread.sleep(3); 
      } 
     } 

жаль, что я забыл поставить теги комментариев // в на линии, что сказал делать то, что каждый вам нужно сделать здесь.

Что это такое - он просматривает каждый файл в каталоге и проверяет, можно ли его переименовать, если переименование не сработало и продолжает проверять, пока оно не сможет переименовать, и в какой момент вы можете делать то, что вам нужно с файлом, который в моем случае был всем после цикла for, который был заменен. Мне любопытно, почему мой тент был просмотрен как дополнительный элемент, удаленный и заблокированный. Это решение действительно работает и решает мою проблему, и кто-то другой, у кого есть такая же проблема, пытается обработать файл, который все еще записывается или копируется в каталог, который отслеживается для изменений.

+0

(Я не голосовал.) Не работает для меня, Windows 10, Java 1.8.0_144. У меня есть один JVM для создания и записи в файлы. Другой пытается определить, когда файлы можно перемещать с помощью Files.move(). Я продолжаю получать перемещенные файлы размером 0, которые затем все еще записываются так, как будто местоположение не имеет значения. Во всяком случае, я просто добавил файл file.renameTo (файл) непосредственно перед моей командой move, и если он вернет false, я сразу же System.exit(). Но программа никогда не выходит в этом месте. –

3

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

+0

На самом деле это не так просто, как кажется на Windows. Мое решение, реализованное в этих строках, работает в 99,5% случаев (подробнее см. Http://stackoverflow.com/questions/29923008/how-to-create-then-automically-rename-file-in-java-on-windows) –

0

Используйте «файл флага»: как только файл.txt «завершен», укажите это, создав файл.flg - процесс потребления должен дождаться появления .flg.

Смежные вопросы