如何使用最小的 C# 代码将一个 Stream 复制到一个字节数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/950513/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:03:39  来源:igfitidea点击:

How to copy one Stream to a byte array with the smallest C# code?

c#.netstream

提问by Jader Dias

Until now I am counting 12 LoCs. Could you make it smaller?

到目前为止,我正在计算 12 个 LoC。你能把它变小吗?

using (Stream fileStream = File.OpenRead(fileName))
{
    using (BinaryReader binaryReader = new BinaryReader(fileStream))
    {
        using (MemoryStream memoryStream = new MemoryStream())
        {
            byte[] buffer = new byte[256];
            int count;
            int totalBytes = 0;
            while ((count = binaryReader.Read(buffer, 0, 256)) > 0)
            {
                memoryStream.Write(buffer, 0, count);
                totalBytes += count;
            }
            memoryStream.Position = 0;
            byte[] transparentPng = new byte[totalBytes];
            memoryStream.Read(transparentPng, 0, totalBytes);
        }
    }
}

采纳答案by Noldorin

There's a static method that can do this for you in one call.

有一种静态方法可以在一次调用中为您完成此操作。

var data = File.ReadAllBytes(fileName);

Alternatively, a method that works for any Stream(that returns its length) would be:

或者,适用于任何Stream(返回其长度)的方法是:

byte[] data;
using (var br = new BinaryReader(stream))
    data = br.ReadBytes((int)stream.Length);

For streams that don't have a well-defined length (e.g. NetworkStream), and thus raise an exception on calling stream.Length, this of course does not work. The slightly more complicated solution presented in Jon Skeet's answer is then what you probably want.

对于没有明确定义的长度(例如NetworkStream)的流,因此在调用时引发异常stream.Length,这当然不起作用。Jon Skeet 的答案中提出的稍微复杂的解决方案就是您可能想要的。

回答by Joel Coehoorn

How 'bout one:

一个怎么样:

byte[] result = File.ReadAllBytes(fileName);

回答by Garry Shutler

While not reducing the LOC (I'd never use this as a primary motivation), you can collapse the usings like this:

虽然不减少 LOC(我永远不会将此作为主要动机),但您可以像这样折叠使用:

using (Stream fileStream = File.OpenRead(fileName))
using (BinaryReader binaryReader = new BinaryReader(fileStream))
using (MemoryStream memoryStream = new MemoryStream())
{
    byte[] buffer = new byte[256];
    int count;
    int totalBytes = 0;
    while ((count = binaryReader.Read(buffer, 0, 256)) > 0)
    {
        memoryStream.Write(buffer, 0, count);
        totalBytes += count;
    }
    memoryStream.Position = 0;
    byte[] transparentPng = new byte[totalBytes];
    memoryStream.Read(transparentPng, 0, totalBytes);    
}

回答by Jon Skeet

Reducing your lines of code is pretty simple here (while still working with arbitrary streams, rather than just files):

减少代码行数在这里非常简单(同时仍然使用任意流,而不仅仅是文件):

using (Stream fileStream = File.OpenRead(fileName))
using (MemoryStream memoryStream = new MemoryStream())
{
    int byteRead;
    while ((byteRead = fileStream.ReadByte()) != -1)
    {
        memoryStream.WriteByte(byteRead);
    }
    return memoryStream.ToArray();
}

Obviously it's a lot more efficientto read into a buffer than to read a byte at a time, but this reduces the number of statements (as you don't need to declare both a buffer anda variable to hold the return value from Stream). Calling MemoryStream.ToArray()is simpler than reading into a newly constructed array.

显然,读取缓冲区比一次读取一个字节要高效得多,但这会减少语句的数量(因为您不需要同时声明缓冲区变量来保存来自 Stream 的返回值) . 调用MemoryStream.ToArray()比读入新构造的数组更简单。

Using a buffer is nicer though. Note that we really don't need BinaryReader:

不过使用缓冲区更好。请注意,我们真的不需要 BinaryReader:

using (Stream fileStream = File.OpenRead(fileName))
using (MemoryStream memoryStream = new MemoryStream())
{
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        memoryStream.Write(buffer, 0, bytesRead);
    }
    return memoryStream.ToArray();
}

If you want to be reallybrutal, we could reduce the number of usingstatements (with either solution):

如果您想变得非常残酷,我们可以减少using语句的数量(使用任一解决方案):

using (Stream fileStream = File.OpenRead(fileName),
              memoryStream = new MemoryStream())
{
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
    {
        memoryStream.Write(buffer, 0, bytesRead);
    }
    return ((MemoryStream)memoryStream).ToArray();
}

But that's just nasty :)

但这只是讨厌:)

Another option of course is to use a library such as MiscUtilwhich has a method to read fully from a stream :) The utility method can be as simple as this:

当然,另一种选择是使用诸如MiscUtil 之类的库,它具有从流中完全读取的方法:) 实用程序方法可以像这样简单:

public static byte[] ReadFully(this Stream stream)
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
        {
            memoryStream.Write(buffer, 0, bytesRead);
        }
        return memoryStream.ToArray();
    }
}

Note that this nevercloses the stream - the caller should do that.

请注意,这永远不会关闭流 - 调用者应该这样做。

回答by C. Augusto Proiete

Just use the CopyTomethod of the Streamto copy to a MemoryStream, and get the array:

只需使用 the 的CopyTo方法Stream复制到 a MemoryStream,并获取数组:

using (var fileStream = File.OpenRead(fileName))
{
    using (var memoryStream = new MemoryStream())
    {
        fileStream.CopyTo(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);

        byte[] transparentPng = memoryStream.ToArray();
    }
}