如何创建与文件大小相同的缓冲区?

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

我想避免设置固定大小的缓冲区,因为文件太大或太小以致缓冲区中有空白空间。

ArenaAllocator
听起来很有希望,因为您可以根据需要分配更多空间。是否有“正确”的方法来执行此操作,即加载作为命令行参数传递到缓冲区的 .json 文件?

zig
4个回答
4
投票

如何创建与文件大小相同的缓冲区?

您可以请求文件大小并分配相同数量的内存:

const file = try std.fs.cwd().openFile("file.txt", .{}));
defer file.close();

const file_size = (try file.stat()).size;
const buffer = try allocator.alloc(u8, file_size);

然后您可以使用

readNoEof
:

来读取文件
try file.reader().readNoEof(buffer);

或者,您可以使用

File
readToEndAlloc
功能:

const size_limit = std.math.maxInt(u32); // or any other suitable limit
const result = try file.readToEndAlloc(allocator, size_limit);

2
投票

使用

GeneralPurposeAllocator
。您可以在 https://youtu.be/vHWiDx_l4V0

了解有关分配器的更多信息
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = &gpa.allocator;
    const args = try std.process.argsAlloc(allocator);
    defer std.process.argsFree(allocator, args);
    const file = try std.fs.cwd().openFile(args[1], .{});
    const file_content = try file.readToEndAlloc(allocator, 1024 * 1024); // 1MB max read size
    defer allocator.free(file_content);
    std.debug.print("{s}", .{file_content});
}

2
投票

在 0.10.0-dev.2345+9747303d1 上,这对我有用:

const std = @import("std");

pub fn main() !void {
    var file = try std.fs.cwd().openFile("test.ts", .{ .mode = .read_only });
    const file_size = (try file.stat()).size;
    const allocator = std.heap.page_allocator;
    var buffer = try allocator.alloc(u8, file_size);
    try file.reader().readNoEof(buffer);

    std.debug.print("{s}\n", .{buffer});
}

OpenFlags
.openFile
定义如下: https://github.com/ziglang/zig/blob/master/lib/std/fs/file.zig#L80


2
投票

今天在 Zig 中没有一个答案对我有用,因为一些接口发生了变化(例如分配器 -> 分配器())。这是对我有用的方法(2022 年 12 月):

const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = &gpa.allocator();
    var file = try std.fs.cwd().openFile("./sample.txt", .{});
    const file_content = try file.readToEndAlloc(allocator.*, 10 * 1024 * 1024); // 10MB read
    defer allocator.free(file_content);
    std.debug.print("{s}", .{file_content});
}
© www.soinside.com 2019 - 2024. All rights reserved.