Gibt es einen einfachen Weg oder eine Methode zur Konvertierung einer Stream
in eine byte[]
C#で?
- Erstellen eines Byte-Arrays aus einem Stream (18 Antworten )
Antworten
Zu viele Anzeigen?Nächste Funktion aufrufen wie
byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);
Funktion:
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;
}
}
}
Ich verwende diese Erweiterungsklasse:
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();
}
}
}
Kopieren Sie die Klasse einfach in Ihre Lösung und Sie können sie in jedem Stream verwenden:
byte[] bytes = myStream.ReadAllBytes()
Funktioniert hervorragend für alle meine Streams und spart eine Menge Code! Natürlich können Sie diese Methode ändern, um einige der anderen Ansätze hier zu verwenden, um die Leistung zu verbessern, wenn nötig, aber ich mag es einfach zu halten.
In .NET Framework 4 und später wird die Stream
Klasse hat eine eingebaute CopyTo
Methode, die Sie verwenden können.
Für frühere Versionen des Frameworks ist die praktische Hilfsfunktion zu haben:
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);
}
Verwenden Sie dann eine der oben genannten Methoden, um in ein MemoryStream
und rufen GetBuffer
darauf:
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 : Ursprünglich hatte ich vorgeschlagen, Jasons Antwort für eine Stream
die die Length
Eigentum. Aber sie hatte einen Fehler, weil sie davon ausging, dass die Stream
würde den gesamten Inhalt in einer einzigen Read
was nicht unbedingt wahr ist (nicht für eine Socket
zum Beispiel). Ich weiß nicht, ob es ein Beispiel für eine Stream
Implementierung in der BCL, die Folgendes unterstützt Length
aber möglicherweise die Daten in kürzeren Stücken zurückgeben, als Sie anfordern, aber da jeder die Daten erben kann Stream
könnte dies leicht der Fall sein.
In den meisten Fällen ist es wahrscheinlich einfacher, die obige allgemeine Lösung zu verwenden, aber angenommen, Sie wollen direkt in ein Array lesen, das bigEnough
:
byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
offset += r;
Das heißt, Sie rufen wiederholt Read
und verschieben Sie die Position, an der Sie die Daten speichern wollen.
- See previous answers
- Weitere Antworten anzeigen