Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从流创建字节数组_C#_.net 3.5_Inputstream - Fatal编程技术网

C# 从流创建字节数组

C# 从流创建字节数组,c#,.net-3.5,inputstream,C#,.net 3.5,Inputstream,从输入流创建字节数组的首选方法是什么 这是我目前使用.NET3.5的解决方案 Stream s; byte[] b; using (BinaryReader br = new BinaryReader(s)) { b = br.ReadBytes((int)s.Length); } 读写流的块是否仍然是一个更好的主意?这实际上取决于您是否可以信任s.Length。对于许多流,您不知道将有多少数据。在这种情况下,在.NET 4之前,我会使用如下代码: public static byt

从输入流创建字节数组的首选方法是什么

这是我目前使用.NET3.5的解决方案

Stream s;
byte[] b;

using (BinaryReader br = new BinaryReader(s))
{
    b = br.ReadBytes((int)s.Length);
}

读写流的块是否仍然是一个更好的主意?

这实际上取决于您是否可以信任
s.Length
。对于许多流,您不知道将有多少数据。在这种情况下,在.NET 4之前,我会使用如下代码:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}
public static byte[] StreamToByteArray(Stream stream)
{
    if (stream is MemoryStream)
    {
        return ((MemoryStream)stream).ToArray();                
    }
    else
    {
        // Jon Skeet's accepted answer 
        return ReadFully(stream);
    }
}
对于.NET4和更高版本,我会使用,这基本上相当于我代码中的循环-创建
MemoryStream
,调用
stream.CopyTo(ms)
,然后返回
ms.ToArray()
。工作完成了

也许我应该解释一下为什么我的答案比其他答案长。并不能保证它会阅读所有要求的内容。例如,如果您正在从网络流读取数据,它可能会读取一个数据包的值,然后返回,即使很快会有更多数据。将一直运行到流的结尾或指定的大小,但您仍然必须知道要开始的大小

上述方法将继续读取(并复制到
内存流中
),直到数据耗尽。然后它要求
MemoryStream
返回数组中的数据副本。如果您知道要开始的大小-或者认为您知道大小,但不确定-您可以将
MemoryStream
构造为要开始的大小。同样,您可以在末尾进行检查,如果流的长度与缓冲区的大小相同(由返回),那么您可以只返回缓冲区。因此,上面的代码并没有得到很好的优化,但至少是正确的。它不承担关闭流的任何责任-调用者应该这样做


有关更多信息(以及替代实现),请参阅。

只想指出,如果您有一个MemoryStream,那么您已经有了
MemoryStream.ToArray()

此外,如果您正在处理未知或不同子类型的流,并且您可以收到
MemoryStream
,您可以在这些情况下使用上述方法,而在其他情况下仍然使用公认的答案,如下所示:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16*1024];
    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
}
public static byte[] StreamToByteArray(Stream stream)
{
    if (stream is MemoryStream)
    {
        return ((MemoryStream)stream).ToArray();                
    }
    else
    {
        // Jon Skeet's accepted answer 
        return ReadFully(stream);
    }
}

Bob(即提问者)的代码出现编译时错误。Stream.Length是一个长参数,而BinaryReader.ReadBytes采用整数参数。在我的例子中,我不希望处理的流足够大,需要很长的精度,因此我使用以下方法:

Stream s;
byte[] b;

if (s.Length > int.MaxValue) {
  throw new Exception("This stream is larger than the conversion algorithm can currently handle.");
}

using (var br = new BinaryReader(s)) {
  b = br.ReadBytes((int)s.Length);
}

虽然Jon的回答是正确的,但他正在重写
CopyTo
中已经存在的代码。因此,对于.NET4,请使用Sandip的解决方案,但对于.Net的早期版本,请使用Jon的答案。Sandip的代码可以通过使用“using”来改进,因为在许多情况下,
CopyTo
中的异常很可能会导致
MemoryStream
无法处理

public static byte[] ReadFully(Stream input)
{
    using (MemoryStream ms = new MemoryStream())
    {
        input.CopyTo(ms);
        return ms.ToArray();
    }
}

您甚至可以通过扩展使其更美观:

名称空间Foo
{
公共静态类扩展
{
公共静态字节[]ToByteArray(此流)
{
使用(流)
{
使用(MemoryStream memStream=new MemoryStream())
{
stream.CopyTo(memStream);
返回memStream.ToArray();
}
}
}
}
}
然后将其作为常规方法调用:

byte[] arr = someStream.ToByteArray()

上面的一个是可以的…但是当你通过SMTP发送东西时,你会遇到数据损坏(如果你需要的话)。我已更改为其他有助于正确逐字节发送的内容: "

使用系统;
使用System.IO;
私有静态字节[]已就绪(字符串输入)
{
FileStream sourceFile=newfilestream(输入,FileMode.Open);//打开拖缆
BinaryReader=新的BinaryReader(源文件);
字节[]输出=新字节[sourceFile.Length];//创建大小文件的字节数组
for(长i=0;i
只要我的几分钱。。。我经常使用的做法是将这样的方法组织为自定义帮助器

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
}

将名称空间添加到配置文件中,并在您希望的任何位置使用它

我能够使它在一行上工作:

byte [] byteArr= ((MemoryStream)localStream).ToArray();

如上所述,上述代码仅适用于MemoryStream。您可以使用此扩展方法

public static byte[] ToByteArray(Stream stream)
    {
        if (stream is MemoryStream)
        {
            return ((MemoryStream)stream).ToArray();
        }
        else
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }            
    }
public static class StreamExtensions
{
    public static byte[] ToByteArray(this Stream stream)
    {
        var bytes = new List<byte>();

        int b;
        while ((b = stream.ReadByte()) != -1)
            bytes.Add((byte)b);

        return bytes.ToArray();
    }
}
公共静态类StreamExtensions
{
公共静态字节[]ToByteArray(此流)
{
var bytes=新列表();
int b;
而((b=stream.ReadByte())!=-1)
字节。添加((字节)b);
返回bytes.ToArray();
}
}
您可以简单地使用MemoryStream类的ToArray()方法,例如-

MemoryStream ms = (MemoryStream)dataInStream;
byte[] imageBytes = ms.ToArray();

创建一个helper类,并在您希望使用它的任何地方引用它

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            input.CopyTo(ms);
            return ms.ToArray();
        }
    }
}

如果有人喜欢,这里有一个.NET4+唯一的解决方案,它是作为扩展方法形成的,没有对MemoryStream进行不必要的Dispose调用。这是一个微不足道的优化,但值得注意的是,未能处理MemoryStream并不是真正的失败

public static class StreamHelpers
{
    public static byte[] ReadFully(this Stream input)
    {
        var ms = new MemoryStream();
        input.CopyTo(ms);
        return ms.ToArray();
    }
}

这是我正在使用的功能,经过测试,运行良好。 请记住,“input”不应为null,“input.position”应在读取之前重置为“0”,否则将中断读取循环,并且不会读取任何内容以转换为数组

    public static byte[] StreamToByteArray(Stream input)
    {
        if (input == null)
            return null;
        byte[] buffer = new byte[16 * 1024];
        input.Position = 0;
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            byte[] temp = ms.ToArray();

            return temp;
        }
    }

在命名空间RestSharp.Extensions中有方法ReadAsBytes。在这个方法中使用了MemoryStream,在本页的一些示例中也有相同的代码,但是当您使用RestSharp时,这是最简单的方法

using RestSharp.Extensions;
var byteArray = inputStream.ReadAsBytes();

当然,另一个问题是您是否应该从流中创建一个字节[]。。。对于大数据,最好将流视为流!实际上,您可能应该使用流而不是字节[]。但是有些系统API不支持流。例如,您不能从中创建