Конвертировать StreamReader в byte [] - PullRequest
35 голосов
/ 03 мая 2011

Я получаю объект Streamreader результата.

Я хочу преобразовать результат в байт [].

Как я могу преобразовать Streamreader в байты []?

Спасибо

Ответы [ 5 ]

42 голосов
/ 03 мая 2011

Просто выбросьте все, что вы прочитали, в MemoryStream и получите байтовый массив в конце.Как уже отмечалось, вы должны читать из базового потока, чтобы получить необработанные байты.

var bytes = default(byte[]);
using (var memstream = new MemoryStream())
{
    var buffer = new byte[512];
    var bytesRead = default(int);
    while ((bytesRead = reader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
        memstream.Write(buffer, 0, bytesRead);
    bytes = memstream.ToArray();
}

Или, если вы не хотите управлять буферами:

var bytes = default(byte[]);
using (var memstream = new MemoryStream())
{
    reader.BaseStream.CopyTo(memstream);
    bytes = memstream.ToArray();
}
33 голосов
/ 03 мая 2011

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

2 голосов
/ 07 марта 2015

Вы также можете использовать CopyTo:

var ms = new MemoryStream();
yourStreamReader.BaseStream.CopyTo(ms); // blocking call till the end of the stream
ms.GetBuffer().CopyTo(yourArray, ms.Length);

или

var ms = new MemoryStream();
var ct = yourStreamReader.BaseStream.CopyToAsync(ms);
await ct;
ms.GetBuffer().CopyTo(yourArray, ms.Length);
0 голосов
/ 21 ноября 2016

Для всех, кто говорит, что нужно получить байты, скопируйте его в MemoryStream и т. Д. - если предполагается, что содержимое не должно превышать объем памяти компьютера, разумно ожидать, что можно просто использовать StreamReader 's встроенный ReadLine() или ReadToEnd()?Я видел, что они даже не упоминались, и они делают все для вас.

У меня был сценарий использования, когда я просто хотел сохранить путь к файлу SQLite из FileDialogResult, который пользователь выбирает в процессе синхронизации / инициализации.Затем моей программе необходимо использовать этот путь при запуске для обычных процессов приложения.Возможно, это не идеальный способ сбора / повторного использования информации, но он не сильно отличается от записи / чтения из INI-файла - я просто не хотел устанавливать один для одного значения.Поэтому я просто прочитал его из плоского однострочного текстового файла.Вот что я сделал:

string filePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!filePath.EndsWith(@"\")) temppath += @"\"; // ensures we have a slash on the end
filePath = filePath.Replace(@"\\", @"\"); // Visual Studio escapes slashes by putting double-slashes in their results - this ensures we don't have double-slashes
filePath += "SQLite.txt";

string path = String.Empty;
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
path = sr.ReadLine();  // can also use sr.ReadToEnd();
sr.Close();
fs.Close();
fs.Flush();

return path;

Если вам ДЕЙСТВИТЕЛЬНО нужен byte[] вместо string по какой-то причине, используя мой пример, вы всегда можете сделать:

byte[] toBytes;
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
toBytes = Encoding.ASCII.GetBytes(path);
sr.Close();
fs.Close();
fs.Flush();

return toBytes;

(Возвращая toBytes вместо path.)

Если вы не хотите ASCII, вы можете легко заменить его на UTF8, Unicode и т. Д.

0 голосов
/ 03 мая 2011

Вы можете использовать этот код: Вы не должны использовать этот код:

byte[] bytes = streamReader.CurrentEncoding.GetBytes(streamReader.ReadToEnd());

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

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