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 "";
}
}
이 방법이 도움이되기를 바랍니다.