Почему StreamReader и sr.BaseStream.Seek () предоставляют нежелательные символы даже в кодировке UTF8 - PullRequest
1 голос
/ 13 февраля 2020

Содержимое файла ab c .txt:

ABCDEFGHIJ•XYZ

Теперь показанный символ - это хорошо, если я использую этот код (т. Е. Искать в позиции 9),

            string filePath = "D:\\abc.txt";
            FileStream fs = new FileStream(filePath, FileMode.Open);
            StreamReader sr = new StreamReader(fs, new UTF8Encoding(true), true);
            sr.BaseStream.Seek(9, SeekOrigin.Begin);
            char[] oneChar = new char[1];
            char ch = (char)sr.Read(oneChar, 0, 1);
            MessageBox.Show(oneChar[0].ToString());

Но если позиция SEEK находится сразу после этого специального символа Dot, тогда я получаю символ барахла.

Итак, я получаю символ барахла, если я делаю Seek в позицию 11 (то есть сразу после позиции точки)

sr.BaseStream.Seek(11, SeekOrigin.Begin);

Это должно дать 'X', потому что символ на 11-й позиции - X.

Я думаю, что содержимое файла юридически UTF8.

Есть еще одна вещь, Длина StreamReader BaseStream и длина содержимого StreamReader различны.

   MessageBox.Show(sr.BaseStream.Length.ToString());
   MessageBox.Show(sr.ReadToEnd().Length.ToString());

1 Ответ

2 голосов
/ 13 февраля 2020

Почему StreamReader и sr.BaseStream.Seek () дают символы нежелательной почты даже в кодировке UTF8

Это именно из-за UTF-8, что sr.BaseStream дает ненужные символы. :)

StreamReader - относительно "умный" поток. Он понимает, как строки работают, тогда как FileStream (то есть sr.BaseStream) - нет. FileStream знает только о байтах.

Поскольку ваш файл закодирован в UTF-8 (кодирование переменной длины), такие буквы, как A, B и C, кодируются 1 байтом, но для символа требуется 3 байта. Вы можете получить, сколько байтов нужно персонажу, выполнив:

Console.WriteLine(Encoding.UTF8.GetByteCount("•"));

Таким образом, когда вы перемещаете поток в «позицию сразу после », вы на самом деле не двигаетесь мимо , вы находитесь на втором байте.

Причина, по которой Length различаются, аналогична: StreamReader дает вам количество символов , тогда как sr.BaseStream дает Вы число байтов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...