Java — Как читать только определенные части входного потока

#java #file #io

#java #файл #io

Вопрос:

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

Пример:

 INFO  | 2011-04-13 17:59:22,810 | Calling Feedback from 127.0.0.1 
INFO  | 2011-04-13 17:59:24,920 | Successfully called Feedback from 127.0.0.1
INFO  | 2011-04-13 17:59:31,561 | FeedBackList

ERROR | 2011-04-13 19:00:41,640 |  
java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:228)
    at java.util.concurrent.FutureTask.get(FutureTask.java:91)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java:111)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy309.getConsumerProfileData(Unknown Source)
    at com.scea.usps.model.service.impl.AccountSettingsServiceImpl.getUserProfile(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
    at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java:111)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy284.getUserProfile(Unknown Source)
    at com.scea.usps.model.common.PsninfoUtility.getTop3Generes(Unknown Source)
    at com.scea.usps.model.common.PsninfoUtility.updatePsnInfoDetail(Unknown Source)
    at com.scea.platform.framework.api.PsnInfoThread.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:619)

INFO  | 2011-04-13 17:59:22,810 | Calling Feedback from 127.0.0.1 
INFO  | 2011-04-13 17:59:24,920 | Successfully called Feedback from 127.0.0.1
INFO  | 2011-04-13 17:59:31,561 | FeedBackList
  

В приведенном выше журнале мне нужно извлечь (прочитать) все строки, начиная с ОШИБКИ, до завершения трассировки стека. Пожалуйста, поделитесь своими идеями по этому поводу. Спасибо.

Комментарии:

1. Когда вы говорите «читать только определенные части файла», вы имеете в виду, что вам нужно разобрать их из файла? Я спрашиваю, вы просто ищете алгоритм для анализа соответствующих данных или что-то более сложное? Кроме того, будут ли все «ОШИБКИ» иметь трассировки стека? Являются ли только начальные записи строки ERROR / INFO и newlines? Если это всего лишь базовый вопрос «как мне …», то приведенный ниже ответ Брайана имеет наибольший смысл.

2. Почему анализатор файла журнала должен быть Java?

3. Не уверен, что Chainsaw, logging.apache.org/chainsaw/index.html , могу справиться с этим из коробки, но, возможно, стоит попробовать, прежде чем создавать собственное приложение.

Ответ №1:

 BufferedReader in = new BufferedReader(new FileReader("logfile.log"));
  String line = in.readLine();
  StringBuffer buf = null;
  while (line != null) {
    if(line.startsWith("ERROR")){
       buf = new StringBuffer();
       buf.append(line).append("n");
       while(line != null amp;amp; !line.trim().equals("")){
          line = in.readLine();
          buf.append(line).append("n");
       }
       //Now buf has your error an do whatever you want to do with it
       //then delete
       buf = null;
    }
    line = in.readLine();
  }
  

Комментарии:

1. Спасибо за ответ. Это не работает. Мне нужно напечатать не только 1-ю строку трассировки стека ошибок, но мне также нужно напечатать остальные строки трассировки стека ошибок.

2. @Hitatichi: Мое решение сохраняет в StringBuffer все строки между «ERROR …» и пустой строкой, так что это также сохраняет нужную трассировку стека

Ответ №2:

Если ваша цель — просмотреть журналы вашего приложения на предмет ошибок, то такой инструмент, как Chainsaw, может быть лучшим решением.

Ответ №3:

В Chainsaw действительно есть это встроенное средство, если вы используете LogFilePatternReceiver. Вы можете определить FilterExpression, и будут обрабатываться только события, соответствующие этому filterexpression.

Примером выражения фильтра, которое будет включать только трассировки стека, может быть:

существует исключение

Вы должны указать формат вашего файла журнала. Смотрите JavaDoc для получения дополнительной информации:

http://logging.apache.org/log4j/companions/receivers/apidocs/org/apache/log4j/varia/LogFilePatternReceiver.html

Ответ №4:

  • Открыть файл
  • Читайте, пока не наткнетесь на строку с ОШИБКОЙ
  • Читайте и обрабатывайте строки, пока не наткнетесь на пустую строку после трассировки стека.

Промыть, повторить.

Комментарии:

1. @mike Да, я просто ищу алгоритм для анализа требуемых частей из огромного файла журнала. Да, все ошибки будут иметь трассировки стека.

Ответ №5:

 try {
      BufferedReader in
          = new BufferedReader(new FileReader("logfile.log"));
      String line = in.readLine();
      while (!line.startsWith("ERROR")) {
        line = in.readLine();
        if(line==null){
          //throw exception here, ERROR not found in entire log file
        }
      }
      //HERE line will be your error line
      while (line!=null) {
        line = in.readLine();
        //do something with line
      }
      //here you have reached the end of the file
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  

Комментарии:

1. Спасибо за ответ propmpt. Но что происходит со строками, следующими за строкой ОШИБКИ. Даже эти строки необходимо печатать вместе со строкой ошибки. Пожалуйста, направьте меня в правильном направлении. Спасибо.