如何分块读取流?

问题描述 投票:0回答:1

我正在尝试创建一个可以处理非常大的请求的 HTTP 服务器。为了避免高内存使用,我认为以块的形式读取连接流是最好的选择。

问题是读取

BufferedReader
会锁定,直到读取到 128 个字节。当流关闭时,它最终读取缓冲区并工作。

如何读取当前存储的数据而不是等待缓冲区填满?

我的代码:

const BUFFER_SIZE = 128;

fn process_chunk(chunk: []u8, size: usize) bool{
    std.log.debug("Readed size: {d}", .{size});
    if(std.mem.containsAtLeast(u8, "\r\n", 1, chunk) or size < 128){
        return true;
    }
    return false;
}

fn handleConnection( connection: std.net.Server.Connection) !void{

    var buffer: [BUFFER_SIZE]u8 = undefined;
    const stream_reader = connection.stream.reader().any();

    var reader = std.io.BufferedReader(128, @TypeOf(rr)){.unbuffered_reader = stream_reader};

    while (true) {

        const bbis = try reader.read(&buffer);
        std.log.debug("Readed size: {d}", .{bbis});

        if(process_chunk(&buffer)){
            connection.stream.close();
            return;
        }        
    }    
}

完整输出:

debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
debug: Readed size: 128
buffer chunks zig
1个回答
0
投票

[128]u8
传递给
.read()
基本上是说您要等到 128 个字节可用或直到流结束。

我建议根据您正在实施的协议,阅读任何有用的数据量。 例如,如果您正在读取 64 位整数流,您将按 8 个块读取(或者更好,

readInt(u64, ...)
)。

分块带来的实际性能提升将由 BufferedReader 处理,因此您的代码应该只关心下一步处理可以处理多少字节。 下一个字符或标记、一些前瞻字节数、下一个字段等。

readUntilDelimiter
函数类在这里可能会很好。

© www.soinside.com 2019 - 2024. All rights reserved.