C# - Stream.Read 的偏移量(offset)工作不正确。

6 浏览
0 Comments

C# - Stream.Read 的偏移量(offset)工作不正确。

我有一个如下所示的测试代码。我正在从流中读取数据,然后通过偏移2个位置,再取接下来的2个字节。我希望结果是一个包含2个元素的数组。然而,这并不起作用——偏移量完全被忽略,总是返回完整大小的数组,只有偏移位置的块具有值。但这意味着我的结果表仍然非常大,只是有很多不需要的零值。

我该如何重新编写下面的代码,使得当length = 2且offset = 2时,file.Read()只返回一个长度为2的字节数组,而不是10个?在真实的情况下,我处理的是大文件(>2gigs),所以过滤结果数组不是一个选项。

编辑:由于问题不明确,下面的代码要求我总是定义与流大小相同的输出数组。相反,我希望输出的大小与length相同(在下面的示例中,我想要有`var buffer = new byte[2]`,但这将抛出一个异常,因为file.Read忽略了offset和length,总是返回10个元素(其中只有2个被读取,其余是虚拟的零值)。

private byte[] GetFilePart(int length, int offset)
{
    //构建一些虚拟内容
    var content = new byte[10];
    for (int i = 0; i<10; i++)
    {
        content[i] = 1;
    }
    //从content中读取数据
    var buffer = new byte[10];
    using (Stream file = new MemoryStream(content))
    {
        file.Read(buffer, offset, length);
    }
    return buffer;
}

[![偏移量不起作用](https://i.stack.imgur.com/v3i7G.png)](https://i.stack.imgur.com/v3i7G.png)

0
0 Comments

问题:C#中的Stream.Read偏移量工作不正确。

原因:偏移量(offset)是指向buffer中Stream将要写入字节的位置,而不是指定从content中读取哪些字节。

解决方法:根据具体需求进行调整。如果要跳过流中的字节,可以使用Seek()方法或设置Position属性。如果流不支持定位,可以读取并丢弃一些字节来实现跳过。如果需要只返回特定数量的字节到数组中,可以在调用Read方法时传入指定长度的数组。

示例代码:

// 跳过前7个字节,然后将第8个和第9个字节读取到长度为2的字节数组中
byte[] buf = new byte[2];
file.Position = 7; // 跳过前7个字节
file.Read(buf, 0, buf.Length);
// 读取指定长度的字节到长度为2的字节数组中
byte[] buf = new byte[2];
file.Read(buf, 0, buf.Length);

需要注意的是,并非所有的流都支持定位操作,可以通过Stream.CanSeek属性来检查流是否支持定位。如果流不支持定位,则必须读取并丢弃要跳过的字节。

在使用Stream类的相关方法时,可以参考官方文档进行更详细的了解和使用。

参考链接:[Stream.Read - Microsoft Documentation](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.read?view=net-5.0#System_IO_Stream_Read_System_Byte___System_Int32_System_Int32_)

0