我正在try 对FileStream执行分页之类的操作,函数Get FileStream和number OfChunks以及CurrentChunk,它将FileStream切片为number OfChunks并只返回CurrentChunk的字节,但它只有在CurrentChunk为0时才起作用

public async Task<byte[]> GetStreamChunkAsync(Stream inputStream, int numberOfChunks, int currentChunk)
{
    if (numberOfChunks <= 0 || currentChunk < 0 || currentChunk >= numberOfChunks)
    {
        throw new ArgumentOutOfRangeException("Invalid numberOfChunks or currentChunk values");
    }

    int bufferSize = (int)Math.Ceiling((double)inputStream.Length / numberOfChunks);
    
    int startPosition = currentChunk * bufferSize;
    
    int remainingBytes = (int)Math.Min(bufferSize, inputStream.Length - startPosition);
    
    byte[] buffer =new byte[remainingBytes];

    int bytesRead = await inputStream.ReadAsync(buffer, startPosition, buffer.Length);

    if (bytesRead > 0)
    {
        return buffer;
    }

    // Return null if no bytes were read (unexpected end of stream)
    return null;
}

推荐答案

您不应该手动设置位置.这条小溪无论如何都会向前推进.

您确实有另一个问题:您需要一个读取循环,因为缓冲区可能没有填满.读取循环将如下所示

    int bytesRead
    while ((bytesRead = await inputStream.ReadAsync(buffer, startPosition, buffer.Length) > 0)
    {
        startPosition += bytesRead;
        if (startPosition == buffer.Length)
            break;
    }

或者你可以用ReadAtLeastAsync

var bytesRead = await inputStream.ReadAtLeastAsync(buffer, buffer.Length, throwOnEndOfStream: false);

话虽如此,我建议你改用新的异步迭代器功能,这意味着你可以在这上面做await foreach分.

您还可以返回Memory<byte>,这在返回最后一个部分块时效率更高,否则必须将其复制到新的数组中.

public async IAsyncEnumerable<Memory<byte>> GetStreamChunksAsync(Stream inputStream, int numberOfChunks)
{
    if (numberOfChunks <= 0)
    {
        throw new ArgumentOutOfRangeException(nameof(numberOfChunks), numberOfChunks, "Invalid numberOfChunks or currentChunk values");
    }

    int bufferSize = (int)Math.Ceiling((double)inputStream.Length / numberOfChunks);

    while (true)
    {
        byte[] buffer = new byte[bufferSize];
        var bytesRead = await inputStream.ReadAtLeastAsync(buffer, buffer.Length, throwOnEndOfStream: false);
        if (bytesRead > 0)
            yield return buffer.AsMemory(0, bytesRead);
        if (bytesRead < buffer.Length)
            break;
    }
}

然后像这样使用它

await using var fs = File.Open("SomeFile");
await foreach (var chunk in GetStreamChunksAsync(fs, 10)
{
    // do stuff with chunk
}

Csharp相关问答推荐

NumPy s fftn in C#with pythonnet'

如何在Windows 11任务调度程序中每1分钟重复一次任务?

为什么我的表单在绑定到对象时提交空值?

无法通过绑定禁用条目

在静态模式下实例化配置

C#使用TextFieldParser读取.csv,但无法使用";0";替换创建的列表空条目

使用Dapper映射联接查询对象数据到使用SplitOn;

C#Null判断处理失败

CA1508:';NULL=>;TRUE;始终为';TRUE';.移除或重构条件(S)以避免死代码

在字符串C#之前获取数字

对于PowerShell中的ConvertTo-SecureString方法,Microsoft如何将初始化向量添加到AES加密中的安全字符串?

如何在.NET AOT中为所有枚举启用JsonStringEnumConverter

同一组件的多个实例触发相同的事件处理程序

Azure Functions v4中的Serilog控制台主题

实体框架-IsRequired()与OnDelete()

解决方案:延长ABP框架和ANGING OpenIddict中的令牌生命周期

忽略Visual Studio代码中的StyleCop规则

使用SQL Server 2022+时,我是否必须将代码从SqlConnection类对象中迁移出来?

Excel将';@';添加到具有范围的公式中

MudRadioGroup不切换