2013-11-15 4 views
-1

Я разрабатываю какую-то программу, которая должна читать файлы журнала и я думал, что я построил умный механизм в нем, оказывается, код даже не компилировать ...Thread.sleep зовущего Thread.sleep

Я сделал большой недостаток дизайна: как это исправить?

public class Reader implements Runnable { 
    private volatile boolean isReading; 

    private final File file; 

    public Reader(final File file) { 
     this.file = file; 
    } 

    @Override 
    public void run() { 
     BufferedReader reader = null; 
     try { 
      reader = new BufferedReader(new FileReader(file)); 
     } catch (FileNotFoundException ex) { 
      throw new IllegalStateException("bf4logreader.Reader.run: File has not been found. file = " + file); 
     } 
     while (isReading) { 
      String line = null; 
      try { 
       line = reader.readLine(); 
      } catch (IOException ex) { 
       throw new IllegalStateException("bf4logreader.Reader.run: Something went wrong when reading file. file = " + file); 
      } 
      if (line == null) { 
       //No new lines 
       long startSleepTime = System.currentTimeMillis(); 
       try { 
        Thread.sleep(SLEEP_TIME); 
       } catch (InterruptedException ex) { 
        if (isReading) { 
         //Not supposed to be interrupted 
         Thread.sleep(System.currentTimeMillis() - startSleepTime); 
        } 
        else { 
         try { 
          //Needs to shutdown 
          reader.close(); 
         } catch (IOException ex1) { 
          Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex1); 
         } 
        } 
       } 
      } 
      else { 
       //Process new lines 
       System.out.println("Line: " + line); 
      } 
     } 
    } 

    public void shutdown() { 
     isReading = false; 
    } 
} 

Я думал, что быть умным и пусть нить спать в течение времени, он все еще должен был спать, если она была прервана unappropiately. Однако я могу, конечно, не делать этого в этой фракции, так как это потребует обработки Thread.sleepInterrruptedException.

Я думаю, что это необходимо для преобразования в цикл while, но как это сделать?

EDIT: Извините, что я забыл придать идею этой программе. Но я хочу следить за журнальным файлом, поэтому он никогда не перестанет читать этот файл, за исключением случаев, когда я укажу на это с сообщением об отключении.

+0

попытаться выкинуть всю часть 'if (line == null)'. 'reader.readLine()' должен блокироваться, пока не будет чего-то читать. – zapl

+2

@zapl не будет достигнут конец файла. –

+0

Я бы предположил, что как только поток прерывается, он должен прекратить делать то, что он делает. –

ответ

1

Попробуйте следующий код вместо:

try (BufferedReader reader = new BufferedReader(new FileReader(file))) { 
    String line; 
    while (running) { 
    while ((line = reader.readLine()) != null) { 
     System.out.println(line); 
    } 
    Thread.sleep(1000); // end of file has been reached, wait a second for more data 
    } 
} catch (FileNotFoundException ex) { 
    // ... 
} catch (IOException ex) { 
    // ... 
} catch (InterruptedException ex) { 
} 

try (ressource) catch идиома будет гарантировать, что читатель закрыта должным образом при любых обстоятельствах, так что вам не придется беспокоиться об этом.

Функция readLine() автоматически блокирует (помещает текущее исполнение в режим ожидания) до тех пор, пока данные не будут доступны, поэтому нет необходимости в каких-либо спящих режимах или подобном. Если он возвращает null, конец файла будет достигнут, поэтому вы можете выйти.

Если возникло исключение InterruptedException, поток будет правильно завершен. Это исключение всегда вызывается как сигнал к потоку, чтобы прекратить работу как можно скорее, поэтому вы никогда не должны его игнорировать.

Обработка общего исключения, такого как исключение IOException путем выброса совершенно другого исключения, обычно неверна, поскольку она скрывает фактическую причину ошибки. Вместо этого просто обработайте ошибку, наложенную на вас в первую очередь.
Кроме того, IllegalStateException - это исключение RuntimeException, которое обычно не попадает нигде, в результате чего весь ваш код сразу заканчивается. Вы, вероятно, этого не хотите.

+1

Простите, что я забыл поставить его в свой пост. Но идея состоит в том, что он будет следить за журнальным файлом, поэтому я не хочу уходить, когда EOF достигнут. – skiwi

+0

Я добавил для этого часть. Однако вам нужно беспокоиться об эксклюзивной блокировке файлов. – TwoThe

0

Проверьте, помогает ли это

RandomAccessFile in = new RandomAccessFile("/home/hduser/Documents/Sample.txt", "r"); 
     String line; 
     long length = 0;//used to check the file length 
     while (true) { 
      if(in.length()<length){//new condition to reset position if file length is reduced 
       in.seek(0); 
      } 
      if ((line = in.readLine()) != null) { 
       System.out.println(line); 
       length = in.length(); 
      } else { 
       Thread.sleep(2000); 
      } 
     } 
-1

Вы не можете, как ответ, но попытаться использовать оболочки istead написания программы Java. Я сам Java-разработчик, но если только я слышу, что есть что-то делать с журналами, я пытаюсь использовать оболочку unix/linux. Написание кода Java потребует от вас в 20 раз больше времени, вы, вероятно, не найдете все крайние случаи, и будет сложно что-либо изменить, потому что ваша программа будет составлять 200 строк кода, а не 5.

И ваш код. Это далеко не идеально, хотя ваша забота о том, что это не компиляция. Здесь у вас есть сэр, который будет компилировать и даже работать. Сортировка:

import java.io.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Reader implements Runnable { 
    private volatile boolean isReading; 

    private final File file; 

    public Reader(final File file) { 
    this.file = file; 
    } 

    @Override 
    public void run() { 
    BufferedReader reader; 
    try { 
     reader = new BufferedReader(new FileReader(file)); 
    } catch (FileNotFoundException ex) { 
     throw new IllegalStateException("bf4logreader.Reader.run: File has not been found. file = " + file); 
    } 
    isReading = true; 
    while (isReading) { 
     String line; 
     try { 
     line = reader.readLine(); 
     } catch (IOException ex) { 
     throw new IllegalStateException("bf4logreader.Reader.run: Something went wrong when reading file. file = " + file); 
     } 
     if (line == null) { 
     //No new lines 
     long startSleepTime = System.currentTimeMillis(); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException ex) { 
      if (isReading) { 
      //Not supposed to be interrupted 
      try { 
       Thread.sleep(System.currentTimeMillis() - startSleepTime); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      } 
      else { 
      try { 
       //Needs to shutdown 
       reader.close(); 
      } catch (IOException ex1) { 
       Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex1); 
      } 
      } 
     } 
     } 
     else { 
     //Process new lines 
     System.out.println("Line: " + line); 
     } 
    } 
    } 

    public void shutdown() { 
    isReading = false; 
    } 


    public static void main(String[] args) throws InterruptedException { 

    Reader reader = new Reader(new File("res/integers.txt")); 
    new Thread(reader).start(); 
    Thread.sleep(1000); 
    reader.shutdown(); 
    } 
} 
+0

Если вы собираетесь предлагать иногда другое, чем Java, то, пожалуйста, добавьте это в ответ, тем более, когда вы укажете, что вы использовали его сами. К сожалению, в конечном итоге это будет работать на Windows Server. Кроме того, ваше предложение Java не подходит для случая, когда произошло второе прерывание. – skiwi

+0

Мне жаль разочаровывать вас своим собственным кодом;). – goroncy

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