---
title: "Cheatsheet: Operações de I/O em Zig"
url: "https://ziglang.com.br/cheatsheets/cheatsheet-opera%C3%A7%C3%B5es-de-i/o-em-zig/"
markdown_url: "https://ziglang.com.br/cheatsheets/cheatsheet-opera%C3%A7%C3%B5es-de-i/o-em-zig.MD"
description: "Referência rápida para operações de I/O em Zig: leitura e escrita de arquivos, stdin, stdout, stderr, buffers, streams e operações com diretórios. Guia completo em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# Cheatsheet: Operações de I/O em Zig

Referência rápida para operações de I/O em Zig: leitura e escrita de arquivos, stdin, stdout, stderr, buffers, streams e operações com diretórios. Guia completo em português.


# Cheatsheet: Operações de I/O em Zig

Zig oferece um sistema de I/O robusto e performático através da biblioteca padrão `std.fs` e `std.io`. O design prioriza controle explícito sobre buffers, tratamento de erros obrigatório e composição de readers/writers via interfaces genéricas.

## Stdout, Stdin e Stderr

### Escrita em stdout

```zig
const std = @import("std");

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

    try stdout.print("Olá, {s}!\n", .{"mundo"});
    try stdout.writeAll("Texto direto sem formatação\n");

    // Escrever bytes brutos
    try stdout.writeAll(&[_]u8{ 72, 105, 10 }); // "Hi\n"

    // Escrever byte único
    try stdout.writeByte('Z');
    try stdout.writeByte('\n');
}
```

### Leitura de stdin

```zig
const std = @import("std");

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

    try stdout.writeAll("Digite seu nome: ");

    // Ler uma linha (até \n, máximo 256 bytes)
    var buffer: [256]u8 = undefined;
    const linha = try stdin.readUntilDelimiterOrEof(&buffer, '\n');

    if (linha) |nome| {
        try stdout.print("Olá, {s}!\n", .{nome});
    }
}
```

### Stderr para erros e debug

```zig
const std = @import("std");

pub fn main() !void {
    const stderr = std.io.getStdErr().writer();
    try stderr.print("ERRO: {s}\n", .{"arquivo não encontrado"});

    // Ou usar std.debug.print (sempre vai para stderr)
    std.debug.print("Debug: valor = {d}\n", .{42});
}
```

## Operações com Arquivos

### Ler arquivo inteiro

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Ler arquivo inteiro para string
    const conteudo = try std.fs.cwd().readFileAlloc(
        allocator,
        "dados.txt",
        1024 * 1024, // máximo 1MB
    );
    defer allocator.free(conteudo);

    std.debug.print("Conteúdo: {s}\n", .{conteudo});
}
```

### Ler arquivo linha por linha

```zig
const std = @import("std");

pub fn main() !void {
    const arquivo = try std.fs.cwd().openFile("dados.txt", .{});
    defer arquivo.close();

    var buf_reader = std.io.bufferedReader(arquivo.reader());
    const reader = buf_reader.reader();

    var linha_buf: [4096]u8 = undefined;
    var numero_linha: usize = 1;

    while (try reader.readUntilDelimiterOrEof(&linha_buf, '\n')) |linha| {
        std.debug.print("{d}: {s}\n", .{ numero_linha, linha });
        numero_linha += 1;
    }
}
```

### Escrever em arquivo

```zig
const std = @import("std");

pub fn main() !void {
    // Criar/sobrescrever arquivo
    const arquivo = try std.fs.cwd().createFile("saida.txt", .{});
    defer arquivo.close();

    const writer = arquivo.writer();

    try writer.writeAll("Primeira linha\n");
    try writer.print("Valor: {d}\n", .{42});
    try writer.print("Data: {s}\n", .{"2026-02-21"});
}
```

### Append em arquivo existente

```zig
const std = @import("std");

pub fn main() !void {
    const arquivo = try std.fs.cwd().openFile("log.txt", .{
        .mode = .write_only,
    });
    defer arquivo.close();

    // Ir para o final do arquivo
    try arquivo.seekFromEnd(0);

    const writer = arquivo.writer();
    try writer.print("[INFO] Nova entrada de log\n", .{});
}
```

## Buffered I/O

Buffers melhoram a performance reduzindo chamadas ao sistema:

```zig
const std = @import("std");

pub fn main() !void {
    const arquivo = try std.fs.cwd().createFile("grande.txt", .{});
    defer arquivo.close();

    // Writer com buffer — muito mais rápido para muitas escritas pequenas
    var buf_writer = std.io.bufferedWriter(arquivo.writer());
    const writer = buf_writer.writer();

    for (0..10000) |i| {
        try writer.print("Linha {d}\n", .{i});
    }

    // IMPORTANTE: flush para garantir que tudo foi escrito
    try buf_writer.flush();
}
```

## Operações com Diretórios

```zig
const std = @import("std");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Diretório atual
    const cwd = std.fs.cwd();

    // Criar diretório
    cwd.makeDir("novo_dir") catch |err| switch (err) {
        error.PathAlreadyExists => {},
        else => return err,
    };

    // Criar diretórios recursivamente
    try cwd.makePath("a/b/c/d");

    // Listar conteúdo de diretório
    var dir = try cwd.openDir(".", .{ .iterate = true });
    defer dir.close();

    var iter = dir.iterate();
    while (try iter.next()) |entrada| {
        const tipo = switch (entrada.kind) {
            .file => "arquivo",
            .directory => "diretório",
            .sym_link => "link simbólico",
            else => "outro",
        };
        std.debug.print("{s}: {s}\n", .{ tipo, entrada.name });
    }

    // Caminhos absolutos
    var path_buf: [std.fs.max_path_bytes]u8 = undefined;
    const caminho_abs = try cwd.realpath(".", &path_buf);
    std.debug.print("Diretório atual: {s}\n", .{caminho_abs});

    // Deletar arquivo
    cwd.deleteFile("temp.txt") catch {};

    // Deletar diretório vazio
    cwd.deleteDir("novo_dir") catch {};

    // Deletar diretório recursivamente
    cwd.deleteTree("a") catch {};

    // Renomear
    try cwd.rename("antigo.txt", "novo.txt");

    // Verificar se existe
    _ = cwd.statFile("arquivo.txt") catch |err| {
        if (err == error.FileNotFound) {
            std.debug.print("Arquivo não existe\n", .{});
        }
        _ = allocator; // apenas para evitar unused
    };
}
```

## Caminhos (Paths)

```zig
const std = @import("std");

pub fn main() void {
    const caminho = "/home/usuario/projeto/src/main.zig";

    // Basename — nome do arquivo
    const nome = std.fs.path.basename(caminho);
    std.debug.print("Nome: {s}\n", .{nome}); // main.zig

    // Dirname — diretório pai
    const dir = std.fs.path.dirname(caminho);
    std.debug.print("Dir: {s}\n", .{dir orelse "(nulo)"}); // /home/usuario/projeto/src

    // Extensão
    const ext = std.fs.path.extension(caminho);
    std.debug.print("Ext: {s}\n", .{ext}); // .zig

    // Stem — nome sem extensão
    const stem = std.fs.path.stem(caminho);
    std.debug.print("Stem: {s}\n", .{stem}); // main
}
```

## Tabela de Referência — std.fs

| Operação | Método | Exemplo |
|----------|--------|---------|
| Abrir arquivo | `openFile(path, flags)` | `try cwd.openFile("a.txt", .{})` |
| Criar arquivo | `createFile(path, flags)` | `try cwd.createFile("a.txt", .{})` |
| Ler tudo | `readFileAlloc(alloc, path, max)` | `try cwd.readFileAlloc(alloc, "a.txt", 1e6)` |
| Deletar arquivo | `deleteFile(path)` | `try cwd.deleteFile("a.txt")` |
| Criar diretório | `makeDir(path)` | `try cwd.makeDir("dir")` |
| Criar dirs recursivo | `makePath(path)` | `try cwd.makePath("a/b/c")` |
| Deletar diretório | `deleteDir(path)` | `try cwd.deleteDir("dir")` |
| Renomear | `rename(old, new)` | `try cwd.rename("a", "b")` |
| Stat | `statFile(path)` | `try cwd.statFile("a.txt")` |

## Tabela de Referência — Reader/Writer

| Reader | Descrição |
|--------|-----------|
| `readAll(buf)` | Ler até encher o buffer |
| `readUntilDelimiterOrEof(buf, delim)` | Ler até delimitador ou EOF |
| `readByte()` | Ler um byte |
| `readInt(T, endian)` | Ler inteiro com endianness |
| `skipBytes(n, .{})` | Pular N bytes |

| Writer | Descrição |
|--------|-----------|
| `writeAll(bytes)` | Escrever todos os bytes |
| `print(fmt, args)` | Escrever formatado |
| `writeByte(byte)` | Escrever um byte |
| `writeInt(T, val, endian)` | Escrever inteiro com endianness |

## Erros Comuns

```zig
// ERRO: Esquecer de fechar arquivo
// const f = try cwd.openFile("x.txt", .{});
// ... sem close()

// CORRETO: Sempre usar defer
const f = try std.fs.cwd().openFile("x.txt", .{});
defer f.close();

// ERRO: Esquecer flush do buffer
// buf_writer escreveu mas não fez flush

// CORRETO: Sempre fazer flush
try buf_writer.flush();

// ERRO: Buffer muito pequeno para readUntilDelimiterOrEof
// var buf: [10]u8 = undefined; // pode estourar
// CORRETO: buffer generoso ou usar allocator
```

## Veja Também

- [Formatação (fmt)](/cheatsheets/fmt-formatacao/) — Especificadores de formato
- [Strings](/cheatsheets/strings/) — Manipulação de strings e bytes
- [Error Handling](/cheatsheets/error-handling/) — Tratamento de erros de I/O
- [Allocators](/cheatsheets/allocators/) — Alocação para leituras dinâmicas
- [Receitas](/receitas/) — Exemplos práticos de I/O
