如何在 C# 中将 Stream 转换为 byte[]?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1080442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert an Stream into a byte[] in C#?
提问by pupeno
Is there a simple way or method to convert an Streaminto a byte[]in C#?
有没有一种简单的方法或方法可以在 C# 中将an 转换Stream为 a byte[]?
采纳答案by pedrofernandes
Call next function like
调用下一个函数,如
byte[] m_Bytes = StreamHelper.ReadToEnd (mystream);
Function:
功能:
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;
}
}
}
回答by jason
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;
}
A slightly more complicated solution is necesary is s.Lengthexceeds Int32.MaxValue. But if you need to read a stream that large into memory, you might want to think about a different approach to your problem.
稍微更复杂的解决方案是necesary是s.Length超过Int32.MaxValue。但是,如果您需要将如此大的流读取到内存中,您可能需要考虑采用不同的方法来解决您的问题。
Edit: If your stream does not support the Lengthproperty, modify using Earwicker's workaround.
编辑:如果您的流不支持该Length属性,请使用 Earwicker 的解决方法进行修改。
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();
回答by Phil Price
Quick and dirty technique:
快速而肮脏的技术:
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);
}
I would ask, why do you want to read a stream into a byte[], if you are wishing to copy the contents of a stream, may I suggest using MemoryStream and writing your input stream into a memory stream.
我会问,为什么要将流读入字节 [],如果您希望复制流的内容,我是否建议使用 MemoryStream 并将输入流写入内存流。
回答by Daniel Earwicker
In .NET Framework 4 and later, the Streamclass has a built-in CopyTomethod that you can use.
在 .NET Framework 4 及更高版本中,Stream该类具有CopyTo您可以使用的内置方法。
For earlier versions of the framework, the handy helper function to have is:
对于该框架的早期版本,具有的方便的辅助函数是:
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);
}
Then use one of the above methods to copy to a MemoryStreamand call GetBufferon it:
然后使用上述方法之一复制到aMemoryStream并调用GetBuffer它:
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:originally I suggested using Jason's answer for a Streamthat supports the Lengthproperty. But it had a flaw because it assumed that the Streamwould return all its contents in a single Read, which is not necessarily true (not for a Socket, for example.) I don't know if there is an example of a Streamimplementation in the BCL that does support Lengthbut might return the data in shorter chunks than you request, but as anyone can inherit Streamthis could easily be the case.
编辑:最初我建议使用 Jason 的答案来Stream支持该Length属性。但它有一个缺陷,因为它假设 theStream将在单个 中返回其所有内容Read,这不一定是真的(Socket例如,不是 a 。)我不知道StreamBCL 中是否有实现的示例确实支持Length但可能会以比您请求的更短的块返回数据,但由于任何人都可以继承,Stream这很容易发生。
It's probably simpler for most cases to use the above general solution, but supposing you did want to read directly into an array that is bigEnough:
在大多数情况下,使用上述通用解决方案可能更简单,但假设您确实想直接读入一个数组bigEnough:
byte[] b = new byte[bigEnough];
int r, offset;
while ((r = input.Read(b, offset, b.Length - offset)) > 0)
offset += r;
That is, repeatedly call Readand move the position you will be storing the data at.
也就是说,重复调用Read并移动您将存储数据的位置。
回答by SwDevMan81
You could also try just reading in parts at a time and expanding the byte array being returned:
您也可以尝试一次只读取部分内容并扩展返回的字节数组:
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;
}
回答by Sharon AS
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
回答by James Dingle
The shortest solution I know:
我知道的最短的解决方案:
using(var memoryStream = new MemoryStream())
{
sourceStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
回答by Vinicius
Ok, maybe I'm missing something here, but this is the way I do it:
好吧,也许我在这里遗漏了一些东西,但这是我的方式:
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;
}
回答by Savas Adar
if you post a file from mobile device or other
如果您从移动设备或其他设备发布文件
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
}
回答by Tavo
Byte[] Content = new BinaryReader(file.InputStream).ReadBytes(file.ContentLength);

