Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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代码将一个流复制到字节数组?_C#_.net_Stream - Fatal编程技术网

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

C# 如何用最小的C代码将一个流复制到字节数组?,c#,.net,stream,C#,.net,Stream,到目前为止,我数的是12个LOC。你能小一点吗 using (Stream fileStream = File.OpenRead(fileName)) { using (BinaryReader binaryReader = new BinaryReader(fileStream)) { using (MemoryStream memoryStream = new MemoryStream()) { byte[] buffe

到目前为止,我数的是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);
        }
    }
}
一个怎么样:

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

有一个静态方法可以在一次调用中为您实现这一点

var data = File.ReadAllBytes(fileName);
或者,适用于任何
(返回其长度)的方法是:

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

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

在不减少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);    
}

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

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

不过,使用缓冲区更好。请注意,我们确实不需要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();
}
如果您想变得非常残忍,我们可以使用语句减少
的数量(使用任一解决方案):

但这太糟糕了:)

当然,另一种选择是使用一个库,例如它有一个方法可以完全读取流:)实用程序方法可以如下所示:

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();
    }
}

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

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

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

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

“如果它能工作,为什么这很重要?”只要不必维护代码,这并不重要;-)+1表示“为什么重要…”有时最简洁的不是最可读的(或最有效的)。不过,在这种情况下,File.ReadAllBytes是很难被击败的。我试图指出的一点(很糟糕)是,目标不应该是减少LOC,而应该是提高清晰度。在任何一天,我都会用30行清晰的代码来代替4行模糊的疯狂代码。data=binaryReader.ReadBytes(stream.Length);应该是data=br.ReadBytes(stream.Length);有人试过这个吗?br.ReadBytes接受int参数和流。长度为long。它不会编译,但通过简单的强制转换很容易修复。如果流的长度大于最大Int32值,那么无论如何您都不想这样做!虽然它只适用于文件当然。。。它与原始问题中的代码匹配,但与问题的标题不匹配:)很好。也许如果我以后觉得无聊,我会用一个接受开放流作为输入的函数来表达这一点——对于所有的代码片段,还没有人费心去写函数签名。正如我在回答中所展示的,对于一个长度你知道的流来说,这并不复杂。对于长度未知的流,您可能可以编写一个3/4行扩展方法来完成此工作。
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();
    }
}
using (var fileStream = File.OpenRead(fileName))
{
    using (var memoryStream = new MemoryStream())
    {
        fileStream.CopyTo(memoryStream);
        memoryStream.Seek(0, SeekOrigin.Begin);

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