1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Zig 0.15.1以降のReader/Writerの使い方

Last updated at Posted at 2025-09-10

はじめに

zigのバージョン0.15.1において、Writergateの名の下にstd.io.Readerstd.io.Writerが廃止され、std.Io.Readerstd.Io.Writerに置き換えられた。12

気付いた範囲での変更点のメモ。

std.fs.FileからのReaderの取得

(旧) std.fs.File.reader(self: *File) Reader
(新)std.fs.File.reader(self: *File, buffer: []u8) Reader

新APIではバッファを要求するようになった。

var file = try std.fs.openFileAbsolute("/path/to/");
defer file.deinit();
var buffer: [4096]u8 = undefined; // お好きなサイズで
var reader = file.reader(&buffer);

ファイルの一括読み込み

(旧)std.fs.File.readToEndAlloc(self: File, allocator: Allocator, max_bytes: usize) ![]u8
(新)std.Io.Reader.allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocError![]u8

完全にお引越。
新APIではmax_byteslimitに置き換わった。
Limitの定義は以下。

pub const Limit = enum(usize) {
    nothing = 0,
    unlimited = std.math.maxInt(usize),
    pub fn limited(n: usize) Limit { ...} // 任意サイズ
    pub fn limited64(n: u64) Limit { ...} // 任意サイズ
    
    // (snip)
}

allocRemainingの中で呼んでいるappendRemainingのコードを見ると、

  • nothing: 読まずに.StreamTooLongを返す
  • unlimited: ストリームの末端まで読む(ファイルなら一括読み込み)
  • limited/limited64: 指定した上限まで読み込む。読みきれなければ.StreamTooLongを返す

std.fs.FileからのReaderの取得に従ってReaderを取得して、Limit.unlimitedを指定することで、ファイルの一括読み込みができる。
std.fs.File.Readerinterfaceフィールドを経由することでstd.Io.Readerが取得できる。

0.13.1: https://ziglang.org/documentation/0.13.0/std/#std.fs.File.readToEndAlloc
0.15.1: https://ziglang.org/documentation/0.15.1/std/#std.Io.Reader.allocRemaining

センチネル付きでファイルを読み込む

(旧)readToEndAllocOptions( self: File, allocator: Allocator, max_bytes: usize, size_hint: ?usize, comptime alignment: u29, comptime optional_sentinel: ?u8, ) !(if (optional_sentinel) |s| [:s]align(alignment) u8 else []align(alignment) u8)
(新)なくなりました〜

バージョン0.15.1では後方互換性で旧APIがまだ使えるので、これで耐え凌ぎましょう。
開発バージョンの0.16.0では

(新)allocRemainingAlignedSentinel( r: *Reader, gpa: Allocator, limit: Limit, comptime alignment: std.mem.Alignment, comptime sentinel: ?u8, ) LimitedAllocError!(if (sentinel) |s| [:s]align(alignment.toByteUnits()) u8 else []align(alignment.toByteUnits()) u8)

が追加されている。

旧APiの引数の違いとして、alignmentがcomptime u29からstd.mem.Alignmentに変更。

std.mem.Alignmentの定義は以下

pub const Alignment = enum(math.Log2Int(usize)) {
    @"1" = 0,
    @"2" = 1,
    @"4" = 2,
    @"8" = 3,
    @"16" = 4,
    @"32" = 5,
    @"64" = 6,
    // (snip)

Null終端C文字列として読みたい場合は.@"8"を指定すればよい。

ちなみに0.16.0において、std.fs.Dirには、readFileAllocOptionsがまだ残ってる。
なんだこのチグハグなAPIは(毒)

0.13.1: https://ziglang.org/documentation/0.13.0/std/#std.fs.File.readToEndAllocOptions
0.16.0: https://ziglang.org/documentation/master/std/#std.Io.Reader.allocRemainingAlignedSentinel

Writer経由でのバッファへの書き出し

0.13.1まではstd.ArrayListを構築、ついでstd.ArrayList.readerでジェネリックReaderを取得して、書き出しが行えた。

0.15.1ではジェネリックReaderの廃止に伴い、std.Io.Writer.Allocatingが追加されたのでこれを使う。
std.Io.Writer.Allocating.writerフィールドを経由することでstd.Io.Writerが取得できる。

何だこの一貫性のないAPIは(毒)

const hello = "Hello world";

var writer = std.Io.Writer.Allocating.init(allocator);
writer.deinit();

try writer.writer.writeAll(hello);
const content = try writer.toOwnedSlice();

0.13.1: https://ziglang.org/documentation/0.13.0/std/#std.io.Reader
0.15.1: https://ziglang.org/documentation/0.15.1/std/#std.Io.Writer.Allocating

std.fs.AtomicFileのコンストラクタ

(旧)init( dest_basename: []const u8, mode: File.Mode, dir: Dir, close_dir_on_deinit: bool, ) InitError!AtomicFile
(新)init( dest_basename: []const u8, mode: File.Mode, dir: Dir, close_dir_on_deinit: bool, write_buffer: []u8, ) InitError!AtomicFile

引数が一つ足され、バッファを要求している。
std.fs.FileからのReaderの取得と同様に、バッファを渡す。

var buffer: [4096]u8 = undefined;
var tmp_file = try std.fs.AtomicFile.init("/path/to/", std.fs.File.default_mode, std.fs.cwd(), false, &buffer);
defer tmp_file.deinit();

try tmp_file.file_writer.interface.writeAll(new_content);
try tmp_file.finish();

0.13.1: https://ziglang.org/documentation/0.13.0/std/#std.fs.AtomicFile.init
0.15.1: https://ziglang.org/documentation/0.15.1/std/#std.fs.AtomicFile.init

  1. わかりづらいけどIが大文字になってる

  2. 0.15.1の時点では、後方互換性維持のためまだ残されてるけど、コメントにいずれお前を消すと書かれている

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?