одновременное чтение и запись файла в C#

У меня есть файл, содержащий данные, которые я хотел бы отслеживать изменения, а также добавлять собственные изменения. Думайте как " хвост - фу фу.формат txt."

на основе этой теме, похоже, я должен просто создать filestream и передать его как писателю, так и читателю. Однако, когда читатель достигает конца исходного файла, он не видит обновлений, которые я пишу сам.

Я знаю, что это кажется странной ситуации... больше его эксперимент, чтобы увидеть, если это может быть сделанный.

вот пример, который я пробовал:


foo.txt:
а
б
c
d
e
f


        string test = "foo.txt";
        System.IO.FileStream fs = new System.IO.FileStream(test, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);

        var sw = new System.IO.StreamWriter(fs);
        var sr = new System.IO.StreamReader(fs);

        var res = sr.ReadLine();
        res = sr.ReadLine();
        sw.WriteLine("g");
        sw.Flush();
        res = sr.ReadLine();
        res = sr.ReadLine();
        sw.WriteLine("h");
        sw.Flush();
        sw.WriteLine("i");
        sw.Flush();
        sw.WriteLine("j");
        sw.Flush();
        sw.WriteLine("k");
        sw.Flush();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();

после прохождения "f" считыватель возвращает значение null.

5 ответов


Ok, два изменения позже...

Это должно работать. В первый раз, когда я попробовал, я думаю, что забыл установить FileMode.Добавить в поток.

string test = "foo.txt";

var oStream = new FileStream(test, FileMode.Append, FileAccess.Write, FileShare.Read); 
var iStream = new FileStream(test, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

var sw = new System.IO.StreamWriter(oStream);
var sr = new System.IO.StreamReader(iStream); 
var res = sr.ReadLine(); 
res = sr.ReadLine();
sw.WriteLine("g"); 
sw.Flush(); 
res = sr.ReadLine();
res = sr.ReadLine();
sw.WriteLine("h"); sw.Flush();
sw.WriteLine("i"); sw.Flush(); 
sw.WriteLine("j"); sw.Flush(); 
sw.WriteLine("k"); sw.Flush(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine();
res = sr.ReadLine();
res = sr.ReadLine();
res = sr.ReadLine();

@mikerobi правильно, когда вы пишете в поток, указатель файла изменяется и перемещается в конец потока. Вы не рассчитываете на то, что StreamReader имеет свой собственный буфер. Он считывает 1024 байта из файла, и вы получите результаты из буфера. Пока буфер не закончится, поэтому он должен снова прочитать из FileStream. Ничего не найти, потому что указатель файла находится в конце файла.

вам действительно нужно отделить потоки файлов, каждый со своим собственным файлом у меня есть надежда, что это сработает.


Я считаю, что каждый раз, когда вы пишете символ, вы продвигаете позицию потока, поэтому следующее чтение пытается прочитать после символа, который вы только что написали. Это происходит из-за того, что средство чтения потока и средство записи потока используют один и тот же поток файлов. Используйте другой поток файлов или ищите -1 символ в потоке после каждой записи.


маловероятно, что вы будете довольны любым решением этой проблемы, которое включает использование одного и того же потока для чтения и записи. Это особенно верно, если вы пытаетесь прочитать хвост файла с помощью StreamReader.

вы хотите иметь два разных файловых потоков. Поток записи может быть StreamWriter Если вам нравится. Поток чтения должен быть двоичным потоком (т. е. создавать с помощью File.OpenRead или FileStream.Create), чтение необработанных байтов из файла и преобразование в текст. Мой ответ этот вопрос показывает основы того, как это делается.


Если вы добавляете вызов StreamReader.DiscardBufferedData(), Это меняет поведение?