2012-02-29 5 views
2

특정 키워드가 포함 된 줄을 로그 파일에서 검색하고 키워드 중 하나가 발견되면 사용자에게 경고하는 작은 C# 응용 프로그램을 개발 중입니다. 이 로그는 잠재적으로 매우 크며 (최악의 경우 몇 기가 바이트) 로그와 관련된 유일한 행은 응용 프로그램이 실행되는 동안 로그에 추가되는 행입니다.변경 내용을 로그 파일로 캡처

이미 존재하는 파일 내용에 대해 걱정할 필요없이 파일에 추가되는 각 텍스트 줄을 캡처 할 수있는 방법이 있습니까? 솔루션을 검색하는 동안

나는 이미 FileSystemWatcher 구성 클래스에 대해 알게하고, 그 내가 로그에서 가져올 새로운 내용이있을 때 을 알리는 좋은 것 같다 있지만, 나에게 이야기에 대한 도움말하지 않는 것 무엇을이 추가되었습니다.

+1

참조 : http://stackoverflow.com/questions/452902/how-to-read-a-text-file-reverse-with-iterator-in-c-sharp –

+0

제목 앞에 " C# "등. 그것이 바로 태그가있는 것입니다. –

답변

4

FileStream을 읽기 모드 (물론 작성자 허용)로 열어두면 FSW에서 파일이 수정되었음을 알릴 때까지 전체 파일을 처음 스캔하고 끝날 때까지 기다려야합니다.

파일을 삭제하면 읽기 스레드를 어떻게 든 재설정해야합니다. 예를 들어, 사용자가 처리중인 로그 파일이 롤백되는 경우입니다.

public static void Main() 
    { 
     var lockMe = new object(); 
     using (var latch = new ManualResetEvent(true)) 
     using (var fs = new FileStream(@"C:\Temp\Temp.txt", FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite)) 
     using (var fsw = new FileSystemWatcher(@"C:\Temp\")) 
     { 
      fsw.Changed += (s, e) => 
           { 
            lock (lockMe) 
            { 
             if (e.FullPath != @"C:\Temp\Temp.txt") return; 
             latch.Set(); 
            } 
           }; 
      using (var sr = new StreamReader(fs)) 
       while (true) 
       { 
        latch.WaitOne(); 
        lock (lockMe) 
        { 
         String line; 
         while ((line = sr.ReadLine()) != null) 
          Console.Out.WriteLine(line); 
         latch.Set(); 
        } 
       } 
     } 
    } 
+0

작은 텍스트 파일에서 효과적이지만 초기 검색으로 인해 127MB 샘플에서 몇 분이 걸릴 수 있습니다. 전체 파일을 거치지 않는 방법이 있다고 생각하지 않습니까? – Silen

+1

StreamReader를 생성하기 전에 거기에'fs.Seek (0, SeekOrigin.End);'를 추가하면됩니다. –

+0

완벽하게 작동합니다. 정말 고마워요! – Silen

0

가장 효율적인 솔루션 (응용 프로그램에서 필요로하는 경우)은 파일 훅 드라이버를 작성하여 파일에 대한 모든 쓰기 액세스를 캡처하는 것입니다. 이 드라이버는 변경된 바이트 수를 알려줍니다. C/C++에서 드라이버를 작성하지 않으려면 EasyHook을 사용할 수 있습니다. EasyHook은 로그 파일에 쓰는 정확한 응용 프로그램을 알고 있다면 매우 간단한 사용자 모드 후크 (CodePlex에서 그의 예제를 확인하십시오)를 작성할 수 있기 때문에 EasyHook은 훌륭합니다. 응용 프로그램의 이름을 모르는 경우 커널 훅을 작성해야 할 수도 있습니다 (EasyHook을 사용하면 더 쉽습니다).

0

this question과 비슷한 방식으로 이전 파일 크기를 기록해야합니다. 그런 다음 10 줄 바꿈을 찾는 대신 크기 차이를 찾아보십시오. 인코딩에 대해서는주의해야합니다.

+0

훨씬 쉬운 해결책;] – Jason

0

을 대신 파일에서 텍스트를 읽는 (나는 당신이 생각하는 것 : 여기

는, 나는 예 -이 작업을 실행하고, 실행되는 동안, 메모장에 C:\Temp\Temp.txt을 편집하고 저장 함께 노크), 파일의 바이트를 읽습니다. 파일에 대한 쓰기가 항상 추가되고 파일의 텍스트 인코딩을 알고 있다고 가정하면 원래 파일의 파일 크기에서 시작하는 바이트 수만 읽을 수 있습니다. 그런 다음 적절한 인코딩을 사용하여 바이트를 텍스트로 변환하십시오.

+0

흠, 실제로 로그가 항상 추가되므로 전체 파일을 실행하지 않아도되는 견고한 솔루션처럼 보입니다. 시도 해보려합니다. – Silen