Как я могу прочитать текстовый файл без блокировки?
у меня есть служба windows, которая записывает свой журнал в текстовый файл в простом формате.
теперь я собираюсь создать небольшое приложение для чтения журнала службы и показывает как существующий журнал, так и добавленный как live view.
проблема в том, что сервис блокирует текстовый файл для добавления новых строк и в то же время приложение просмотра блокирует файл для чтения.
Сервис-Код:
void WriteInLog(string logFilePath, data)
{
File.AppendAllText(logFilePath,
string.Format("{0} : {1}rn", 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();
}
}
есть ли какие-либо проблемы в моем коде в способе чтения и записи?
Как решить проблему?
7 ответов:
вы должны убедиться, что и служба, и читатель открывают файл журнала не исключительно. Попробуйте это:
для службы используйте экземпляр FileStream, созданный следующим образом:
var outStream = new FileStream(logfileName, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
для чтения используйте то же самое, но измените доступ к файлу:
var inStream = new FileStream(logfileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
удачи!
явная настройка режима общего доступа при чтении текстового файла.
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);
т. е. использовать файловый ресурс.Атрибут ReadWrite на FileStream ().
(нашли на блог Баладжи Рамеша)
вы пробовали скопировать файл, а затем прочитать его?
просто обновляйте копию всякий раз, когда вносятся большие изменения.
этот способ поможет вам быстрее прочитать текстовый файл и без блокировки.
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 ""; } }
надеюсь, этот метод поможет вам.