Здравствуйте, vladpol, Вы писали:
V>Что за ерунда? V>Пытаюсь сдвинуть позицию чтения на шаг назад V>
V>StreamReader _reader;
V> Stream stream = new MemoryStream((new UTF32Encoding().GetBytes(text)), false);
V> _reader = new StreamReader(stream, new UTF32Encoding());
V>//...
V>_reader.BaseStream.Seek(-1, SeekOrigin.Current);
V>
V>Но оказывается, что _reader.BaseStream.Position в этот момент равно _reader.BaseStream.Capacity
Ну так вы прочитали что-то ридером, иначе с чего position поменялось-то?
Проверяйте отладчиком и расставляйте ассерты.
V>И сдвигаюсь я не на шаг назад, а на шаг назад от конца.
Нет, сдвигаетесь вы на шаг назад от текущей позиции. А вот как вы там оказались — это не к ридеру вопрос.
V>Как-то с этой [censored] можно бороться?
Как всегда, изучением матчасти. Сам по себе поток никогда позицию не меняет. StreamReader считывает контент порциями, размер буфера по умолчанию зависит от фреймворка, или 1 кб, или 4. Ставьте точку остановки на MemoryStream.Read (выключить just my code debugging) и смотрите, что там у вас лезет в поток.
P.S. Для смешанного контента вам нужен unbuffered stream reader, что-то типа такого.
Здравствуйте, Nikolay_Ch, Вы писали:
N_C>А зачем Вы дергаете BaseStream? Что Вам мешает дергать Seek у ридера?
А нет его у ридера. System.IO, наследие первого фреймворка, все дела.
Здравствуйте, Sinix, Вы писали:
V>>И сдвигаюсь я не на шаг назад, а на шаг назад от конца. S>Нет, сдвигаетесь вы на шаг назад от текущей позиции. А вот как вы там оказались — это не к ридеру вопрос.
Что вы имеете ввиду? Я читаю один символ , а Position = 200
Здравствуйте, Sinix, Вы писали:
S>Как всегда, для ответа на "и что с этим делать?" нужно знать, какую задачу вы пытаетесь решить и чем вас не устраивает текущее поведение.
У меня простенький лексический анализатор. Посимвольно читаю из потока. В одном хитром случае нужно, грубо говоря, вернуть символ обратно в поток.
Понятно, что можно написать обертку или работать с массивом и т.д. и т.п. Но думал есть более простой способ
Здравствуйте, vladpol, Вы писали:
V>У меня простенький лексический анализатор. Посимвольно читаю из потока. В одном хитром случае нужно, грубо говоря, вернуть символ обратно в поток. V>Понятно, что можно написать обертку или работать с массивом и т.д. и т.п. Но думал есть более простой способ
А, тогда стандартный streamreader вам не совсем подходит. Но ничего не мешает сделать простенькую обёртку, которая будет запоминать, затем откатывать позицию потока и вызывать reader.DiscardBufferedData. Для посимвольного чтения вообще Read() + Peek() достаточно.
P.S. Seek на -1 неправильно в принципе. 1 символ может занимать от 1 до 4 байт, в зависимости от кодировки.
Здравствуйте, vladpol, Вы писали: V>Как-то с этой [censored] можно бороться?
По-простому не получится. У меня была схожая задача — на лету поменять кодировку StreamReader'а.
Но по человечески это сделать нельзя, так как даже если ты вытащишь всю необходимую информацию при помощи отражения из StreamReader'а, останется Decoder, который лежит в нём и может содержать в себе половинки символов. То бишь из потока ты считываешь один байт, а декодер считает, что это управляющая последовательность и просит у тебя ещё 4. И вот эти куски из декодера не выдрать (вроде бы, для этого служит Convert, но он работает обратно здравому смыслу).
В итоге я просто написал собственный StreamReader, чего и тебе желаю. Если тебе не нужна полноценная имплементация TextReader'а, автоматический детект кодировки по преамбуле и прочая хрень, это сделать очень просто. Точно также проинициализируй свой класс кодировкой, получи из неё декодер, заведи внутренний буфер, и читай кусками, вручную контролируя позицию перед каждой операцией.
А если никакого расширения в последствии не будет, то и читай просто по байтам, явно приводя их к Char'ам — нехорошо, но если нужно быстро и топорно, то почему бы и нет. Не придётся возиться с половинчатыми символами и прочей пакостью.
P.S. А вообще стоит описать свою задачу. В повторной обработке одного и того же текста нет ничего хорошего. Возможно, от неё легко можно избавиться?
Здравствуйте, LWhisper, Вы писали:
LW>В итоге я просто написал собственный StreamReader, чего и тебе желаю. Если тебе не нужна полноценная имплементация TextReader'а, автоматический детект кодировки по преамбуле и прочая хрень, это сделать очень просто. Точно также проинициализируй свой класс кодировкой, получи из неё декодер, заведи внутренний буфер, и читай кусками, вручную контролируя позицию перед каждой операцией.
LW>А если никакого расширения в последствии не будет, то и читай просто по байтам, явно приводя их к Char'ам — нехорошо, но если нужно быстро и топорно, то почему бы и нет. Не придётся возиться с половинчатыми символами и прочей пакостью.
Спасибо за совет. Я уже написал свою обертку над StreamReader'ом. Получилось пока может не сильно изящно, но надежно. Модуль, по сути, вспомогательный и хочется сосредоточиться на главной задаче. Если она взлетит — перепишу анализатор