Jak przekonwertować strumień na bajt [] w C#? [duplikat]
To pytanie ma już odpowiedź tutaj:
- tworzenie tablicy bajtów ze strumienia 13 Odpowiedzi
Czy istnieje prosty sposób lub metoda konwersji Stream
na byte[]
W C#?
12 answers
Wywołanie następnej funkcji jak
byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);
Funkcja:
public static byte[] ReadToEnd(System.IO.Stream stream)
{
long originalPosition = 0;
if(stream.CanSeek)
{
originalPosition = stream.Position;
stream.Position = 0;
}
try
{
byte[] readBuffer = new byte[4096];
int totalBytesRead = 0;
int bytesRead;
while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
{
totalBytesRead += bytesRead;
if (totalBytesRead == readBuffer.Length)
{
int nextByte = stream.ReadByte();
if (nextByte != -1)
{
byte[] temp = new byte[readBuffer.Length * 2];
Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
readBuffer = temp;
totalBytesRead++;
}
}
}
byte[] buffer = readBuffer;
if (readBuffer.Length != totalBytesRead)
{
buffer = new byte[totalBytesRead];
Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
return buffer;
}
finally
{
if(stream.CanSeek)
{
stream.Position = originalPosition;
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-24 13:30:03
Najkrótsze rozwiązanie jakie znam:
using(var memoryStream = new MemoryStream())
{
sourceStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-01 06:26:53
W. NET Framework 4 i nowszych, klasa Stream
ma wbudowaną metodę CopyTo
, której możesz użyć.
Dla wcześniejszych wersji frameworka, przydatną funkcją pomocniczą jest:
public static void CopyStream(Stream input, Stream output)
{
byte[] b = new byte[32768];
int r;
while ((r = input.Read(b, 0, b.Length)) > 0)
output.Write(b, 0, r);
}
Następnie użyj jednej z powyższych metod, aby skopiować do MemoryStream
i wywołać GetBuffer
na nim:
var file = new FileStream("c:\\foo.txt", FileMode.Open);
var mem = new MemoryStream();
// If using .NET 4 or later:
file.CopyTo(mem);
// Otherwise:
CopyStream(file, mem);
// getting the internal buffer (no additional copying)
byte[] buffer = mem.GetBuffer();
long length = mem.Length; // the actual length of the data
// (the array may be longer)
// if you need the array to be exactly as long as the data
byte[] truncated = mem.ToArray(); // makes another copy
Edit: pierwotnie zasugerowałem użycie odpowiedzi Jasona dla Stream
, która obsługuje właściwość Length
. Miał jednak wadę, ponieważ zakładał, że Stream
zwróci całą jego zawartość w pojedynczy Read
, co niekoniecznie jest prawdą (np. nie dla Socket
.) Nie wiem, czy istnieje przykład Stream
implementacji w BCL, która obsługuje Length
, ale może zwrócić dane w krótszych fragmentach, niż żądasz, ale ponieważ każdy może dziedziczyć Stream
, może to być łatwo.
Jest prawdopodobnie prostsze w większości przypadków użycie powyższego ogólnego rozwiązania, ale przypuśćmy, że chcesz przeczytać bezpośrednio do tablicy, która jest bigEnough
:
byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
offset += r;
To jest, wielokrotnie wywołaj Read
i przesuń pozycję, w której będą przechowywane dane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-10 16:41:13
byte[] buf; // byte array
Stream stream=Page.Request.InputStream; //initialise new stream
buf = new byte[stream.Length]; //declare arraysize
stream.Read(buf, 0, buf.Length); // read from stream to byte array
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-02 17:47:29
Używam tej klasy rozszerzeń:
public static class StreamExtensions
{
public static byte[] ReadAllBytes(this Stream instream)
{
if (instream is MemoryStream)
return ((MemoryStream) instream).ToArray();
using (var memoryStream = new MemoryStream())
{
instream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
}
Po prostu skopiuj klasę do swojego rozwiązania i możesz jej używać na każdym strumieniu:
byte[] bytes = myStream.ReadAllBytes()
Działa świetnie dla wszystkich moich strumieni i oszczędza dużo kodu! Oczywiście można zmodyfikować tę metodę, aby użyć niektórych innych podejść tutaj, aby poprawić wydajność w razie potrzeby, ale lubię zachować to proste.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-09 14:59:56
Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-13 17:24:33
Ok, może coś mi tu umyka, ale tak to robię:
public static Byte[] ToByteArray(this Stream stream) {
Int32 length = stream.Length > Int32.MaxValue ? Int32.MaxValue : Convert.ToInt32(stream.Length);
Byte[] buffer = new Byte[length];
stream.Read(buffer, 0, length);
return buffer;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 15:31:07
Szybka i brudna technika:
static byte[] StreamToByteArray(Stream inputStream)
{
if (!inputStream.CanRead)
{
throw new ArgumentException();
}
// This is optional
if (inputStream.CanSeek)
{
inputStream.Seek(0, SeekOrigin.Begin);
}
byte[] output = new byte[inputStream.Length];
int bytesRead = inputStream.Read(output, 0, output.Length);
Debug.Assert(bytesRead == output.Length, "Bytes read from stream matches stream length");
return output;
}
Test:
static void Main(string[] args)
{
byte[] data;
string path = @"C:\Windows\System32\notepad.exe";
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read))
{
data = StreamToByteArray(fs);
}
Debug.Assert(data.Length > 0);
Debug.Assert(new FileInfo(path).Length == data.Length);
}
Chciałbym zapytać, dlaczego chcesz odczytać strumień do bajtu [], jeśli chcesz skopiować zawartość strumienia, mogę zasugerować użycie MemoryStream i zapisanie strumienia wejściowego do strumienia pamięci.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-03 18:53:31
Jeśli umieścisz Plik z urządzenia mobilnego lub innego
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-14 20:47:04
Stream s;
int len = (int)s.Length;
byte[] b = new byte[len];
int pos = 0;
while((r = s.Read(b, pos, len - pos)) > 0) {
pos += r;
}
Nieco bardziej skomplikowanym rozwiązaniem jest s.Length
przekroczenie Int32.MaxValue
. Ale jeśli chcesz odczytać strumień tak duży w pamięci, możesz pomyśleć o innym podejściu do problemu.
Edit: jeśli strumień nie obsługuje właściwości Length
, zmodyfikuj ją używając obejścia działania Earwickera .
public static class StreamExtensions {
// Credit to Earwicker
public static void CopyStream(this Stream input, Stream output) {
byte[] b = new byte[32768];
int r;
while ((r = input.Read(b, 0, b.Length)) > 0) {
output.Write(b, 0, r);
}
}
}
[...]
Stream s;
MemoryStream ms = new MemoryStream();
s.CopyStream(ms);
byte[] b = ms.GetBuffer();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:20
Możesz również spróbować po prostu czytać w częściach na raz i rozszerzać zwracaną tablicę bajtów:
public byte[] StreamToByteArray(string fileName)
{
byte[] total_stream = new byte[0];
using (Stream input = File.Open(fileName, FileMode.Open, FileAccess.Read))
{
byte[] stream_array = new byte[0];
// Setup whatever read size you want (small here for testing)
byte[] buffer = new byte[32];// * 1024];
int read = 0;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
stream_array = new byte[total_stream.Length + read];
total_stream.CopyTo(stream_array, 0);
Array.Copy(buffer, 0, stream_array, total_stream.Length, read);
total_stream = stream_array;
}
}
return total_stream;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-06 04:47:23
Tablica"bigEnough" jest trochę naciągnięta. Oczywiście, bufor musi być "duży ebough", ale właściwy projekt aplikacji powinien zawierać transakcje i ograniczniki. W tej konfiguracji każda transakcja będzie miała ustawioną długość, więc Twoja tablica będzie przewidywać określoną liczbę bajtów i wstawiać ją do bufora o prawidłowym rozmiarze. Ograniczniki zapewniłyby integralność transakcji i byłyby dostarczane w ramach każdej transakcji. Aby Twoja aplikacja była jeszcze lepsza, możesz użyć 2 kanałów (2 gniazda). Można by komunikować transakcje komunikatów kontrolnych o stałej długości, które zawierałyby informacje o rozmiarze i numerze sekwencji transakcji danych, które mają być przesłane za pomocą kanału danych. Odbiorca potwierdzi utworzenie bufora i dopiero wtedy dane będą wysyłane. Jeśli nie masz kontroli nad nadawcą strumienia, potrzebujesz wielowymiarowej tablicy jako bufora. Macierze komponentów byłyby wystarczająco małe, aby można było nimi zarządzać i wystarczająco duże, aby były praktyczne w oparciu o szacunki oczekiwanych danych. Proces logika szukałaby znanych ograniczników początkowych, a następnie ograniczników kończących w kolejnych tablicach elementów. Po znalezieniu ogranicznika końcowego utworzony zostanie nowy bufor do przechowywania odpowiednich danych między ogranicznikami, a bufor początkowy musiałby zostać zrestrukturyzowany, aby umożliwić usuwanie danych.
O ile kod do konwersji strumienia na tablicę bajtów jest jeden poniżej.
Stream s = yourStream;
int streamEnd = Convert.ToInt32(s.Length);
byte[] buffer = new byte[streamEnd];
s.Read(buffer, 0, streamEnd);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-19 17:21:33