У меня есть файл, содержащий данные, на которые я хочу отслеживать изменения, а также добавлять собственные изменения. Подумайте, как "Tail -f foo.txt".
Основываясь на этом потоке, похоже, что я должен просто создать фильтр и передать его как писателю, так и читателю. Однако, когда читатель достигает конца исходного файла, он не видит обновления, которые я пишу сам.
Я знаю, что это похоже на странную ситуацию... это скорее эксперимент, чтобы понять, можно ли это сделать.
Вот пример, который я пробовал:
foo.txt:
б
с
d
е
е
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.
Ответ 1
Хорошо, два изменения позже...
Это должно сработать. В первый раз, когда я попробовал это, я думаю, что забыл установить FileMode.Append в oStream.
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();
Ответ 2
@mikerobi правильно, когда вы пишете в поток, указатель файла изменяется и перемещается в конец потока. То, на что вы не рассчитываете, - это то, что StreamReader имеет свой собственный буфер. Он считывает 1024 байта из файла, и вы получите результаты из этого буфера. Пока не закончится буфер, он должен снова прочитать FileStream. Нет ничего, потому что указатель файла находится в конце файла.
Вам действительно нужно отделить FileStreams, каждый со своим собственным указателем на файл, чтобы иметь любую надежду на выполнение этой работы.
Ответ 3
Я считаю, что каждый раз, когда вы пишете символ, вы продвигаете позицию потока, поэтому следующее чтение пытается прочитать после персонажа, который вы только что написали. Это происходит из-за того, что в вашем потоковом считывателе и потоковом потоке используется тот же FileStream. Используйте другой файл, или найдите -1 символов в потоке после каждой записи.
Ответ 4
Очень маловероятно, что вы были бы довольны любым решением этой проблемы, которое предполагает использование одного и того же потока для чтения и записи. Это особенно верно, если вы пытаетесь прочитать хвост файла с помощью StreamReader
.
Вы хотите иметь два разных файла. Поток записи может быть StreamWriter
, если хотите. Поток чтения должен быть двоичным потоком (т.е. Создавать с помощью File.OpenRead
или FileStream.Create
), читать необработанные байты из файла и преобразовывать в текст. Мой ответ на этот вопрос показывает, как это делается.
Ответ 5
Если вы добавляете вызов StreamReader.DiscardBufferedData()
, это изменяет поведение?