2013-01-06 1 views
0

로그 파일 목록을 가지고 있으며 최신 버전의 특정 줄이 있는지 찾아야합니다.가장 업데이트 된 정보가있는 파일 찾기

2013/01/06 16:01:00:283 INFO ag.doLog: xxxx xxxx xxxx xxxx 

그리고 내가 뒤로 스캔하면 나는 줄 내가 파일의 배열을 얻는 방법을 알고

xx/xx/xx xx:xx:xx:xxx INFO ag.doLog: the line i need 

말할 수해야하고, :

파일의 선은 다음과 같이 각 파일 (있는 경우)에서 최신 최신 행을 찾을 수 있습니다.

가장 큰 문제는 파일이 (? 2K 라인) 큰 수와 내가 상대 빠른 방법의 라인 (몇 초)을 찾으려면, 그래서 나는 제안을 열고 오전입니다.

개인 아이디어 : 파일에 X 시간의 행이있는 경우 X 시간 전에 행을 찾지 못한 파일은 더 이상 스캔하지 않아야합니다. 이 모든 파일을 동시에 검색하는 데 필요한, 어떻게 내가 모릅니다.

Atm 코드가 깨지고 메모리가 부족한 것으로 가정합니다.

코드 :

if(files.length>0) { //in case no log files exist 
    System.out.println("files.length: " + files.length); 
    for(int i = 0; i < files.length; i++) { ///for each log file look for string 
     System.out.println("Reading file: " + i + " " + files[i].getName()); 
     RandomAccessFile raf = new RandomAccessFile(files[i].getAbsoluteFile(), "r"); //open log file 
     long lastSegment = raf.length(); //Finds how long is the files 
     lastSegment = raf.length()-5; //Sets a point to start looking 
     String leido = ""; 
     byte array[] = new byte[1024];  
     /* 
     * Going back until we find line or file is empty. 
     */ 
     while(!leido.contains(lineToSearch)||lastSegment>0) { 
      System.out.println("leido: " + leido); 
      raf.seek(lastSegment);   //move the to that point 
      raf.read(array);     //Reads 1024 bytes and saves in array 
      leido = new String(array);  //Saves what is read as a string 
      lastSegment = lastSegment-15; //move the point a little further back 
     } 
     if(lastSegment<0) { 
      raf.seek(leido.indexOf(lineToSearch) - 23); //to make sure we get the date (23 characters long) NOTE: it wont be negative. 
      raf.read(array);     //Reads 1024 bytes and saves in array 
      leido = new String(array);  //make the array into a string 
      Date date = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(leido.substring(0, leido.indexOf(" INFO "))); //get only the date part 
      System.out.println(date); 
      //if date is bigger than the other save file name 
     } 
    } 
} 
+0

그것은 계산 과학 문제 아닌가? – Val

답변

1

나는을 확인하기 어려운 코드 를 찾을 수 있습니다. 파일 끝에서부터 시작까지 줄을 읽는 뒤쪽 판독기에서 작업을 분할 할 수 있습니다. 그리고 파싱 날짜를 현명하게 사용하십시오.

마음, 나는 좋은 코드를하지 않을거야하지만,이 같은 :

public class BackwardsReader implements Closeable { 

    private static final int BUFFER_SIZE = 4096; 

    private String charset; 
    private RandomAccessFile raf; 
    private long position; 
    private int readIndex; 
    private byte[] buffer = new byte[BUFFER_SIZE]; 

    /** 
    * @param file a text file. 
    * @param charset with bytes '\r' and '\n' (no wide chars). 
    */ 
    public BackwardsReader(File file, String charset) throws IOException { 
     this.charset = charset; 
     raf = new RandomAccessFile(file, "r"); 
     position = raf.length(); 
    } 

    public String readLine() throws IOException { 
     if (position + readIndex == 0) { 
      raf.close(); 
      raf = null; 
      return null; 
     } 

     String line = ""; 
     for (;;) { // Loop adding blocks without newline '\n'. 

      // Search line start: 

      boolean lineStartFound = false; 
      int lineStartIndex = readIndex; 
      while (lineStartIndex > 0) { 
       if (buffer[lineStartIndex - 1] == (byte)'\n') { 
        lineStartFound = true; 
        break; 
       } 
       --lineStartIndex; 
      } 
      String line2; 
      try { 
       line2 = new String(buffer, lineStartIndex, readIndex - lineStartIndex, 
         charset).replaceFirst("\r?\n?", ""); 
       readIndex = lineStartIndex; 
      } catch (UnsupportedEncodingException ex) { 
       Logger.getLogger(BackwardsReader.class.getName()) 
         .log(Level.SEVERE, null, ex); 
       return null; 
      } 
      line = line2 + line; 
      if (lineStartFound) { 
       --readIndex; 
       break; 
      } 

      // Read a prior block: 

      int toRead = BUFFER_SIZE; 
      if (position - toRead < 0) { 
       toRead = (int) position; 
      } 
      if (toRead == 0) { 
       break; 
      } 
      position -= toRead; 
      raf.seek(position); 
      raf.readFully(buffer, 0, toRead); 
      readIndex = toRead; 
      if (buffer[readIndex - 1] == (byte)'\r') { 
       --readIndex; 
      } 
     } 
     return line; 
    } 

    @Override 
    public void close() throws IOException { 
     if (raf != null) { 
      raf.close(); 
     } 
    } 
} 

그리고 사용 예 :

public static void main(String[] args) { 
    try { 
     File file = new File(args[0]); 
     BackwardsReader reader = new BackwardsReader(file, "UTF-8"); 
     int lineCount = 0; 
     for (;;) { 
      String line = reader.readLine(); 
      if (line == null) { 
       break; 
      } 
      ++lineCount; 
      System.out.println(line); 
     } 
     reader.close(); 
     System.out.println("Lines: " + lineCount); 
    } catch (IOException ex) { 
     Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 
+0

이것은 답으로 보이는 것 같아 수표에 대한 지연으로 유감스럽게 생각합니다. 현재 문제는 ") : 0"로 끝나는 줄입니다. " 어떻게 든 그들을 null로 가져 가고있다. atm 확인 중. – Juan

+0

패턴이 잘못되어 있어야합니다. 끝은 중요하지 않아야합니다. 어쩌면'ParsePosition pos = new ParsePosition (0); parse (..., pos)'또는 그렇게합니다. –

관련 문제