IOException 使用 .NET 将大文件从 UNC 路径读取到字节数组中

IOException reading a large file from a UNC path into a byte array using .NET

提问人:Matt 提问时间:12/22/2008 最后编辑:John SaundersMatt 更新时间:3/20/2010 访问量:2615

问:

我正在使用以下代码尝试将大文件(280Mb)从UNC路径读入字节数组

public void ReadWholeArray(string fileName, byte[] data)
{
    int offset = 0;
    int remaining = data.Length;

    log.Debug("ReadWholeArray");

    FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

    while (remaining > 0)
    {
        int read = stream.Read(data, offset, remaining);
        if (read <= 0)
            throw new EndOfStreamException
                (String.Format("End of stream reached with {0} bytes left to read", remaining));
        remaining -= read;
        offset += read;
    }
}

这因以下错误而爆炸。

System.IO.IOException: Insufficient system resources exist to complete the requested 

如果我使用本地路径运行它,它可以正常工作,在我的测试用例中,UNC 路径实际上指向本地框。

有什么想法,这是怎么回事?

C# .NET 数组 大文件 UNC

评论


答:

4赞 Jon Skeet 12/22/2008 #1

我怀疑下面的东西正在尝试读取另一个缓冲区,并且一次读取所有 280MB 都失败了。与本地情况相比,网络情况下可能需要更多的缓冲区。

我会一次阅读大约 64K,而不是试图一口气读完。这足以避免分块产生过多的开销,但可以避免需要巨大的缓冲区。

就我个人而言,我倾向于只阅读到流的末尾,而不是假设文件大小保持不变。有关详细信息,请参阅此问题

评论

0赞 Robert Davis 3/20/2010
您使用 4 页内存作为缓冲区有什么特别的原因吗?
0赞 Jon Skeet 3/20/2010
@Robert Davis:重要的大小不是内存页,而是 IO 缓冲区。如果你读取的内容太多,以至于它需要多个 IO 请求,那就有点浪费了——如果你读取的太少,以至于它适合一个请求,而有空余空间,那么反之就是浪费。我的经验是,64K 通常是一个很好的折衷方案,但这取决于较低级别发生的事情。
0赞 Joel Lucsy 12/23/2008 #2

看起来创建的数组大小不足。在传入之前分配了多大的数组?或者您是否假设 Read 函数会根据需要重新分配数据数组?它不会。 编辑:呃,也许不是,我只是注意到你得到的例外。现在不确定。

1赞 John Saunders 3/20/2010 #3

此外,编写的代码需要放入块中。未能释放资源是收到“系统资源不足”的一个非常可能的原因:FileStreamusing

public void ReadWholeArray(string fileName, byte[] data)
{
    int offset = 0;
    int remaining = data.Length;

    log.Debug("ReadWholeArray");

    using(FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        while (remaining > 0)
        {
            int read = stream.Read(data, offset, remaining);
            if (read <= 0)
                throw new EndOfStreamException
                    (String.Format("End of stream reached with {0} bytes left to read", remaining));
            remaining -= read;
            offset += read;
        }
    }
}

评论

0赞 Kevin Brock 3/20/2010
+1.哇,OP > 1 岁了,你注意到了这一点。缓冲区大小可能是主要问题,但这会成为一个问题。
0赞 John Saunders 3/20/2010
@Kevin:我对这个问题进行了编辑(因为乔恩·塞格尔(Jon Seigal)的编辑),它直接跳到了我面前。教训来之不易。