Я хочу записать Строку в Поток (MemoryStream в этом случае) и считать байты один за другим.
stringAsStream = new MemoryStream();
UnicodeEncoding uniEncoding = new UnicodeEncoding();
String message = "Message";
stringAsStream.Write(uniEncoding.GetBytes(message), 0, message.Length);
Console.WriteLine("This:\t\t" + (char)uniEncoding.GetBytes(message)[0]);
Console.WriteLine("Differs from:\t" + (char)stringAsStream.ReadByte());
(Нежелательный) результат, который я получаю:
This: M
Differs from: ?
Похоже, что это не читается правильно, поскольку первым символом "Message" является 'M', который работает при получении байтов от экземпляра UnicodeEncoding, но не при чтении их назад из потока.
Что я делаю неправильно?
Большее изображение: у Меня есть алгоритм, который будет работать над байтами Потока, я хотел бы быть максимально общим и работа с любым Потоком. Я хотел бы преобразовать Строку ASCII в MemoryStream или возможно использовать другой метод, чтобы смочь работать над Строкой как Поток. Рассматриваемый алгоритм будет работать над байтами Потока.
После того, как вы напишете в MemoryStream
и перед тем, как прочитать его обратно, вам нужно Искать
обратно в начало MemoryStream
, чтобы вы не чтение с конца.
ОБНОВЛЕНИЕ
Увидев ваше обновление, я думаю, что есть более надежный способ создания потока:
UnicodeEncoding uniEncoding = new UnicodeEncoding();
String message = "Message";
// You might not want to use the outer using statement that I have
// I wasn't sure how long you would need the MemoryStream object
using(MemoryStream ms = new MemoryStream())
{
var sw = new StreamWriter(ms, uniEncoding);
try
{
sw.Write(message);
sw.Flush();//otherwise you are risking empty stream
ms.Seek(0, SeekOrigin.Begin);
// Test and work with the stream here.
// If you need to start back at the beginning, be sure to Seek again.
}
finally
{
sw.Dispose();
}
}
Как видите, этот код использует StreamWriter для записи всей строки (с правильной кодировкой) в MemoryStream
. Это избавляет от проблем, связанных с записью всего массива байтов для строки.
Обновление: У меня несколько раз возникала проблема с пустым потоком. Достаточно позвонить Flush сразу после того, как вы закончите писать.
Вам необходимо сбросить поток в начало:
stringAsStream.Seek(0, SeekOrigin.Begin);
Console.WriteLine("Differs from:\t" + (char)stringAsStream.ReadByte());
Это также можно сделать, установив для свойства Position
значение 0:
stringAsStream.Position = 0
Я думаю, было бы намного продуктивнее использовать TextWriter
, в данном случае StreamWriter для записи в MemoryStream. После этого, как говорили другие, вам нужно «перемотать» MemoryStream, используя что-то вроде stringAsStream.Position = 0L;
.
stringAsStream = new MemoryStream();
// create stream writer with UTF-16 (Unicode) encoding to write to the memory stream
using(StreamWriter sWriter = new StreamWriter(stringAsStream, UnicodeEncoding.Unicode))
{
sWriter.Write("Lorem ipsum.");
}
stringAsStream.Position = 0L; // rewind
Обратите внимание:
StreamWriter по умолчанию использует экземпляр UTF8Encoding, если не указано иное. Этот экземпляр UTF8Encoding создается без метки порядка байтов (BOM)
Кроме того, вам обычно не нужно создавать новый UnicodeEncoding ()
, поскольку он уже есть в качестве статического члена класса. для использования в удобных вариантах utf-8, utf-16 и utf-32.
И затем, наконец (как говорили другие), вы пытаетесь преобразовать байт
напрямую в char
, а это не так. Если бы у меня был поток памяти и я знал, что это строка, я бы использовал TextReader
, чтобы вернуть строку из байтов. Мне кажется «опасным» возиться с необработанными байтами.
Вы используете message.Length
, который возвращает количество символов в строке, но вы должны использовать для чтения нубмер байт . Вы должны использовать что-то вроде:
byte[] messageBytes = uniEncoding.GetBytes(message);
stringAsStream.Write(messageBytes, 0, messageBytes.Length);
Затем вы читаете один байт и ожидаете получить из него символ, просто приведя его к char
. UnicodeEncoding
будет использовать два байта на символ.
Как говорит Джастин, вы также не пытаетесь вернуться к началу потока.
В принципе, я боюсь, что здесь все не так. Пожалуйста, дайте нам более широкую картину, и мы поможем вам понять, чем вы должны на самом деле делать. Использование StreamWriter
для записи, а затем StreamReader
для чтения - это, возможно, то, что вам нужно, но мы не можем точно сказать, исходя только из того короткого фрагмента кода, который вы показали.