2010-08-10 3 views
70

Windows 서비스에서 로그를 간단한 형식으로 텍스트 파일에 기록합니다.어떻게 텍스트 파일을 잠그지 않고 읽을 수 있습니까?

이제 서비스의 로그를 읽도록 작은 응용 프로그램을 만들고 기존 로그와 추가 된 로그를 모두 라이브 뷰로 표시합니다.

문제는 서비스가 새 줄을 추가하기 위해 텍스트 파일을 잠그는 동시에 뷰어 응용 프로그램이 파일을 읽기 위해 잠그는 것입니다.

서비스 코드 :

void WriteInLog(string logFilePath, data) 
{ 
    File.AppendAllText(logFilePath, 
         string.Format("{0} : {1}\r\n", DateTime.Now, data)); 
} 

뷰어 코드 : 읽기 및 방법을 서면으로 내 코드에 문제가

int index = 0; 
private void Form1_Load(object sender, EventArgs e) 
     { 
      try 
      { 
       using (StreamReader sr = new StreamReader(logFilePath)) 
       { 
        while (sr.Peek() >= 0) // reading the old data 
        { 
         AddLineToGrid(sr.ReadLine()); 
         index++; 
        } 
        sr.Close(); 
       } 

       timer1.Start(); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 


private void timer1_Tick(object sender, EventArgs e) 
     { 
      using (StreamReader sr = new StreamReader(logFilePath)) 
      { 
       // skipping the old data, it has read in the Form1_Load event handler 
       for (int i = 0; i < index ; i++) 
        sr.ReadLine(); 

       while (sr.Peek() >= 0) // reading the live data if exists 
       { 
        string str = sr.ReadLine(); 
        if (str != null) 
        { 
         AddLineToGrid(str); 
         index++; 
        } 
       } 
       sr.Close(); 
      } 
     } 

있습니까?

어떻게 문제를 해결할 수 있습니까?

+0

[StreamReader가 사용 중일 때 StreamReader가 잠기는 것을 방지 할 수 있습니까?] (https://stackoverflow.com/questions/1606349/can-i-prevent-a-streamreader-from-locking) -a-text-file-while-is-use) –

답변

94

서비스와 판독기 모두 비 독점적으로 로그 파일을 열어야합니다. 독자

var outStream = new FileStream(logfileName, FileMode.Open, 
           FileAccess.Write, FileShare.ReadWrite); 

가 동일하게 사용하지만 파일 액세스 변경 :로 만든 파일 스트림 인스턴스가 다음 서비스 이용에 대한

을이 시도

var inStream = new FileStream(logfileName, FileMode.Open, 
           FileAccess.Read, FileShare.ReadWrite); 

행운을 빕니다!

+0

또한 http://stackoverflow.com/questions/5338450/file-readlines-without-locking-it에 ReadLines() 버전이 있습니다. – Colin

+0

완벽 - FileAccess.Read로 File.Open()이 충분하다고 생각 했었지만 아니다. 그래도 그렇습니다. :) – neminem

2

파일 복사를 시도 했습니까?

큰 변경이있을 때마다 사본을 업데이트하십시오.

+1

나는 이것을 시도해 보았지만 최선의 해결책은 아니다. 파일을 복사하는 데 너무 오래 걸립니다. 4MB 파일의 경우 20 초가 걸리기 때문입니다. – Seichi

6

문제는 로그에 쓸 때 파일을 단독으로 잠그기 때문에 StreamReader가 파일을 전혀 열 수 없게된다는 것입니다.

모드로 파일을 열어야합니다.

using (FileStream fs = new FileStream("myLogFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
{ 
    using (StreamReader sr = new StreamReader(fs)) 
    { 
     while (!fs.EndOfStream) 
     { 
      string line = fs.ReadLine(); 
      // Your code here 
     } 
    } 
} 
+0

지금 알다시피'File.ReadAllText()'는 읽기 전용 모드로 실패합니다. –

+0

@modosansreves 그래 나는 [docs] (http://msdn.microsoft.com/en-us/library/ms143368 (v = vs.100) .aspx)에서 그 부분을 삭제했다. 파일이 읽기 전용 인 경우 'UnauthorizedAccessException' - 응답시이를 놓쳤음에 틀림 없음! – James

26

명시 적 텍스트 파일을 읽는 동안 공유 모드를 설정합니다.

using (FileStream fs = new FileStream(logFilePath, 
             FileMode.Open, 
             FileAccess.Read,  
             FileShare.ReadWrite)) 
{ 
    using (StreamReader sr = new StreamReader(fs)) 
    { 
     while (sr.Peek() >= 0) // reading the old data 
     { 
      AddLineToGrid(sr.ReadLine()); 
      index++; 
     } 
    } 
} 
+2

StreamReader.Dispose가 자동으로 닫으므로 스트림을 명시 적으로 닫을 필요가 없습니다. – nothrow

+2

나는 파일 공유가 모두 읽기 및 쓰기 스트림에 설정되어야하며 읽기 만하지 말아야한다고 생각합니다. –

10
new StreamReader(File.Open(logFilePath, 
          FileMode.Open, 
          FileAccess.Read, 
          FileShare.ReadWrite)) 

->이 파일을 잠그지 않습니다.

+0

데이터를 읽을 때 작동합니다. 쓰는 경우 잠긴 파일 오류가 발생합니다. – webzy

5

저는 몇 년 전에 똑같은 일을했습니다. 몇 가지 Google 검색어를 찾은 후 이것을 찾았습니다.

FileStream fs = new FileStream(@”c:\test.txt”, 
            FileMode.Open, 
            FileAccess.Read,   
            FileShare.ReadWrite); 

즉 FileStream()에서 FileShare.ReadWrite 속성을 사용합니다. (Balaji Ramesh's blog에 있음)

0

이 방법은 당신을 도울 것입니다 가장 빠른 텍스트 파일을 읽고 잠금 않고 있습니다.

희망이 방법이 도움이 될 것입니다.

관련 문제