FileStream读写方法的限制

13

FileStream的读/写方法只能接受整数值作为长度。但是FileStream对象返回的长度是长整型。在这种情况下,如果文件大小超过整数值(大约超过2GB),那么FileStream的读/写方法会如何处理长整型值。

FileStream的读/写方法在处理长度时需要使用整数类型的参数,因此它们无法直接处理长整型的长度。如果要处理大于2GB的文件,可以考虑使用其他类似于MemoryMappedFile和BufferedStream的类。
3个回答

13

那么您可以分块读取和写入。无论如何,CLR 对任何特定对象的大小都有限制(即使在 64 位 CLR 上也是如此,约为 2GB)。因此,您不可能有一个足够大以至于成为问题的字节数组。

在读取时,您应该始终循环处理,因为即使还有更多数据要读取,也不能保证 Read 调用将读取与您请求的字节数相同。

编辑:分块读取:

byte[] buffer = new byte[1024 * 32];
int bytesRead;

while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
    // Use the data you've read
}

按照块写作取决于您正在写什么...很难在抽象层面上讨论它。


亲爱的,请提供读取和分块写入的示例。 - jams
@jams:我已经编辑了我的回答,但是不知道你在做什么样的数据处理,很难给出具体的代码。 - Jon Skeet
实际上,我需要从硬盘中读取并写入一个大于2GB的视频文件。我在理解您的分块读写示例方面遇到了困难,但这不是问题,我会处理好的。 - jams
3
亲爱的@JonSkeet,你真是一位宝藏。当我请求你提供示例时,我本来以为你不会提供,因为SO上大多数资深成员对这样愚蠢的请求都表现得很粗鲁。但是你提供了它,因为你有一颗美好的心灵,是一位真正的绅士。祝愿你很快达到30万声望值。 - jams

4

在一次调用中直接写入超过2GB的数据是没有必要的。

如果您确实需要在内存中连续缓冲该数量的数据(可能是使用不安全获取的UnmanagedMemoryStream来实现核心转储?),那么您可以轻松地将写操作分批进行多次调用。无论如何,它都会以512k至当前硬件上的最大4k的块大小写入磁盘。

'流'接口的巨大价值在于您可以任意选择。事实上,当您深入研究时,会发现CLR数组(以及其他任何内容)实际上都限制为2GB

更新

既然您现在已经承认基本上想要复制流,那么您最好使用即时解决方案。这里有一个File.Copy

File.Copy("file-a.txt", "file-new.txt");

或者有标准答案

Stream input
input.CopyTo(output); // .NET 4.0

// .NET 3.5 and others
public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    while (true)
    {
        int read = input.Read (buffer, 0, buffer.Length);
        if (read <= 0)
            return;
        output.Write (buffer, 0, read);
    }
}

不要忘记适时进行流的刷新关闭释放,如果你正在手动处理流的话。祝好!

在回复 OP 的评论“_实际上我需要从硬盘中读写一个大于2GB的视频文件_”中,加入了一些有用的提示。 - sehe

0
据我所知,您仍然可以使用 seek 在流中找到正确的位置。
您可能需要循环来实现这一点,如果您想读取超过 2GB 的数据,您也需要在此处进行循环。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接