std.fs.File em Zig — Referência e Exemplos

std.fs.File — Tipo File e Operações

O tipo std.fs.File representa um descritor de arquivo aberto no sistema operacional. Ele fornece métodos para leitura, escrita, posicionamento, obtenção de metadados e conversão para as interfaces genéricas Reader e Writer.

Visão Geral

Um File é obtido através de operações em Dir (como openFile ou createFile) ou pelas funções getStdOut(), getStdErr() e getStdIn().

const std = @import("std");

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

Campos e Tipos

OpenFlags

pub const OpenFlags = struct {
    mode: enum { read_only, read_write, write_only } = .read_only,
    lock: Lock = .none,
};

CreateFlags

pub const CreateFlags = struct {
    read: bool = false,
    truncate: bool = true,
    exclusive: bool = false,
    lock: Lock = .none,
    mode: u32 = 0o666, // Permissões Unix
};

Stat

pub const Stat = struct {
    inode: u64,
    size: u64,
    mtime: i128,  // Tempo de modificação em nanosegundos
    atime: i128,  // Tempo de acesso
    ctime: i128,  // Tempo de mudança de status
    mode: u32,
};

Métodos Principais

Leitura e Escrita

// Ler para buffer; retorna bytes lidos
pub fn read(self: File, buffer: []u8) ReadError!usize

// Ler exatamente buffer.len bytes
pub fn readAll(self: File, buffer: []u8) ReadError!usize

// Escrever bytes; retorna bytes escritos
pub fn write(self: File, bytes: []const u8) WriteError!usize

// Escrever todos os bytes
pub fn writeAll(self: File, bytes: []const u8) WriteError!void

// Obter reader genérico
pub fn reader(self: File) Reader

// Obter writer genérico
pub fn writer(self: File) Writer

Posicionamento

// Mover cursor para posição absoluta
pub fn seekTo(self: File, pos: u64) SeekError!void

// Mover cursor relativamente
pub fn seekBy(self: File, amt: i64) SeekError!void

// Obter posição atual
pub fn getPos(self: File) GetSeekPosError!u64

// Obter tamanho do arquivo
pub fn getEndPos(self: File) GetSeekPosError!u64

Metadados

// Obter estatísticas do arquivo
pub fn stat(self: File) StatError!Stat

// Definir o tamanho do arquivo
pub fn setEndPos(self: File, length: u64) !void

Controle

// Fechar o arquivo
pub fn close(self: File) void

// Sincronizar dados com disco
pub fn sync(self: File) SyncError!void

// Verifica suporte a escape ANSI
pub fn supportsAnsiEscapeCodes(self: File) bool

Exemplo 1: Leitura e Escrita Completas

const std = @import("std");

pub fn main() !void {
    const cwd = std.fs.cwd();

    // Criar arquivo e escrever dados
    {
        const arquivo = try cwd.createFile("dados.bin", .{});
        defer arquivo.close();

        // Escrever cabeçalho
        try arquivo.writeAll("ZIGF"); // magic bytes

        // Escrever números em formato binário
        const writer = arquivo.writer();
        try writer.writeInt(u32, 42, .little);
        try writer.writeInt(u32, 100, .little);
        try writer.writeInt(u32, 255, .little);

        const stat = try arquivo.stat();
        std.debug.print("Arquivo criado: {d} bytes\n", .{stat.size});
    }

    // Ler o arquivo
    {
        const arquivo = try cwd.openFile("dados.bin", .{});
        defer arquivo.close();

        // Ler magic bytes
        var magic: [4]u8 = undefined;
        _ = try arquivo.readAll(&magic);
        std.debug.print("Magic: {s}\n", .{&magic});

        // Ler números
        const reader = arquivo.reader();
        for (0..3) |i| {
            const valor = try reader.readInt(u32, .little);
            std.debug.print("Valor {d}: {d}\n", .{ i, valor });
        }
    }

    try cwd.deleteFile("dados.bin");
}

Exemplo 2: Posicionamento no Arquivo

const std = @import("std");

pub fn main() !void {
    const cwd = std.fs.cwd();

    const arquivo = try cwd.createFile("posicao.txt", .{ .read = true });
    defer arquivo.close();
    defer cwd.deleteFile("posicao.txt") catch {};

    // Escrever dados
    try arquivo.writeAll("ABCDEFGHIJ0123456789");

    // Voltar ao início
    try arquivo.seekTo(0);

    // Ler os primeiros 5 bytes
    var buf: [5]u8 = undefined;
    _ = try arquivo.readAll(&buf);
    std.debug.print("Posição 0-4: {s}\n", .{&buf}); // ABCDE

    // Pular para posição 10
    try arquivo.seekTo(10);
    _ = try arquivo.readAll(&buf);
    std.debug.print("Posição 10-14: {s}\n", .{&buf}); // 01234

    // Posição atual
    const pos = try arquivo.getPos();
    std.debug.print("Posição atual: {d}\n", .{pos}); // 15

    // Tamanho total
    const tamanho = try arquivo.getEndPos();
    std.debug.print("Tamanho total: {d}\n", .{tamanho}); // 20
}

Exemplo 3: Copiando Arquivos

const std = @import("std");

fn copiarArquivo(cwd: std.fs.Dir, origem: []const u8, destino: []const u8) !void {
    const src = try cwd.openFile(origem, .{});
    defer src.close();

    const dst = try cwd.createFile(destino, .{});
    defer dst.close();

    var buf: [4096]u8 = undefined;
    var total: usize = 0;

    while (true) {
        const n = try src.read(&buf);
        if (n == 0) break;
        try dst.writeAll(buf[0..n]);
        total += n;
    }

    std.debug.print("Copiados {d} bytes: {s} -> {s}\n", .{ total, origem, destino });
}

pub fn main() !void {
    const cwd = std.fs.cwd();

    // Criar arquivo de teste
    {
        const f = try cwd.createFile("original.txt", .{});
        defer f.close();
        try f.writeAll("Conteúdo do arquivo original.\nSegunda linha.\n");
    }

    try copiarArquivo(cwd, "original.txt", "copia.txt");

    // Verificar a cópia
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const conteudo = try cwd.readFileAlloc(gpa.allocator(), "copia.txt", 1024 * 1024);
    defer gpa.allocator().free(conteudo);
    std.debug.print("Conteúdo da cópia:\n{s}", .{conteudo});

    // Limpar
    try cwd.deleteFile("original.txt");
    try cwd.deleteFile("copia.txt");
}

Padrões Comuns

Sempre Usar defer para Fechar

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

Leitura com Buffering

Para muitas leituras pequenas, use BufferedReader:

const arquivo = try cwd.openFile("log.txt", .{});
defer arquivo.close();
var br = std.io.bufferedReader(arquivo.reader());
const reader = br.reader();

Escrita Atômica

const tmp = try cwd.createFile("dados.tmp", .{});
defer tmp.close();
try tmp.writeAll(conteudo);
try tmp.sync(); // Garantir que dados estão no disco
tmp.close();
try cwd.rename("dados.tmp", "dados.txt");

Módulos Relacionados

Tutoriais e Receitas Relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.