Как читать текстовый файл без его блокировки?
У меня есть служба 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();
}
}
Есть ли какие-либо проблемы в моем коде при чтении и записи?
Как решить проблему?
Ответы
Ответ 1
Вам нужно убедиться, что служба и читатель открывают файл журнала не исключительно. Попробуйте следующее:
Для службы используйте экземпляр FileStream, созданный следующим образом:
var outStream = new FileStream(logfileName, FileMode.Open,
FileAccess.Write, FileShare.ReadWrite);
Для читателя используйте то же самое, но измените доступ к файлу:
var inStream = new FileStream(logfileName, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
Удачи!
Ответ 2
Явная настройка режима совместного доступа во время чтения текстового файла.
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++;
}
}
}
Ответ 3
new StreamReader(File.Open(logFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
- > это не блокирует файл.
Ответ 4
Проблема заключается в том, что вы записываете в журнал, что вы блокируете только файл, поэтому StreamReader не сможет открыть его вообще.
Вам нужно попробовать открыть файл в режиме readonly.
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
}
}
}
Ответ 5
Я помню, как пару лет назад делал то же самое. После некоторых запросов Google я нашел это:
FileStream fs = new FileStream(@"c:\test.txt",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite);
то есть. используйте атрибут FileShare.ReadWrite в FileStream().
(найдено на блог Balaji Ramesh)
Ответ 6
Вы пытались скопировать файл, а затем его прочитать?
Просто обновляйте копию всякий раз, когда происходят большие изменения.
Ответ 7
Этот метод поможет вам быстро прочитать текстовый файл и не заблокировать его.
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 "";
}
}
Надеюсь, этот метод поможет вам.