[c#] 잠그지 않고 텍스트 파일을 어떻게 읽을 수 있습니까?

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();
            }
        }

코드를 읽고 쓰는 데 문제가 있습니까?

문제를 해결하는 방법?



답변

서비스와 판독기 모두 로그 파일을 비 배타적으로 열어야합니다. 이 시도:

서비스 (예시의 작성자)의 FileStream경우 다음과 같이 생성 된 인스턴스를 사용 합니다.

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

독자의 경우 동일하게 사용하지만 파일 액세스를 변경하십시오.

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

또한 FileStream구현 IDisposable은 두 경우 모두 using작성기의 경우와 같은 명령문 사용을 고려하는지 확인합니다 .

using(var outStream = ...)
{
   // using outStream here
   ...
}

행운을 빕니다!


답변

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

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++;
        }
    }
}


답변

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

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


답변

문제는 로그에 쓸 때 파일을 독점적으로 잠그기 때문에 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
        }
    }
}


답변

몇 년 전에 똑같은 일을했던 것을 기억합니다. 몇 가지 Google 쿼리 후 다음을 찾았습니다.

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

즉, FileStream ()에서 FileShare.ReadWrite 속성을 사용합니다.

( Balaji Ramesh의 블로그 에서 찾았습니다 )


답변

파일을 복사 한 다음 읽어 보셨습니까?

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


답변

이 방법을 사용하면 잠그지 않고 텍스트 파일을 가장 빠르게 읽을 수 있습니다.

private string ReadFileAndFetchStringInSingleLine(string file)
    {
        StringBuilder sb;
        try
        {
            sb = new StringBuilder();
            using (FileStream fs = File.Open(file, FileMode.Open))
            {
                using (BufferedStream bs = new BufferedStream(fs))
                {
                    using (StreamReader sr = new StreamReader(bs))
                    {
                        string str;
                        while ((str = sr.ReadLine()) != null)
                        {
                            sb.Append(str);
                        }
                    }
                }
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            return "";
        }
    }

이 방법이 도움이되기를 바랍니다.