zig でファイル読み込みは@embedfileが便利

Page content

どうも、たくチャレ(@takuchalle)です。

簡単なスクリプトをzigで書いてみた時に、@embedfileが便利だったので紹介です。

環境

$ zig version
0.11.0-dev.3380+7e0a02ee2

ドキュメントはこちらです。

基本的なファイル読み込み

以下のコードはこちらの記事からの引用ですが、こんな感じでちょっとファイルを読みたいだけなのに記述するコードが多いです。

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

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

    const file_size = try file.getEndPos();
    try stdout.print("file size: {d}\n", .{file_size});

    var reader = std.io.bufferedReader(file.reader());
    var instream = reader.reader();

    const allocator = std.heap. page_allocator;
    const contents = try instream.readAllAlloc(allocator, file_size);
    defer allocator.free(contents);

    try stdout.print("read file value: {c}\n", .{contents});
}

@embedfile を使う

同様のことを@embedFileを使って行います。

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    const inputFile = @embedFile("xxxx");

    try stdout.print("file size: {d}\n", .{inputFile.len});
    try stdout.print("read file value: {s}\n", .{inputFile});
}

@embedFileに指定したファイルをコンパイル時に読み込んで配列に格納してくれるので、ファイル操作のエラー処理などを実行時に行う必要がなくなります。

コンパイル時にファイルがないとコンパイルエラーになりますが、ちょっとしたスクリプトやテストコードでは@embedFileで十分なケースが多いかと思います。