std.fs.cwd() — Diretório de Trabalho Atual
A função std.fs.cwd() retorna um handle Dir que representa o diretório de trabalho atual (Current Working Directory) do processo. Este é o ponto de partida mais comum para operações de sistema de arquivos em Zig, pois permite abrir arquivos e diretórios usando caminhos relativos.
Visão Geral
pub fn cwd() Dir
A função retorna um Dir que pode ser usado para todas as operações de arquivo e diretório relativas ao diretório atual. O Dir retornado não precisa ser fechado (não é um descritor de diretório alocado).
Operações Principais via cwd()
O Dir retornado por cwd() oferece diversos métodos:
Abertura e Criação de Arquivos
// Abrir arquivo existente para leitura
pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File
// Criar ou truncar arquivo
pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File
// Deletar arquivo
pub fn deleteFile(self: Dir, sub_path: []const u8) DeleteFileError!void
// Renomear arquivo
pub fn rename(self: Dir, old: []const u8, new: []const u8) RenameError!void
Operações de Diretório
// Abrir subdiretório
pub fn openDir(self: Dir, sub_path: []const u8, flags: Dir.OpenDirOptions) OpenError!Dir
// Criar diretório
pub fn makeDir(self: Dir, sub_path: []const u8) MakeDirError!void
// Criar diretórios recursivamente
pub fn makePath(self: Dir, sub_path: []const u8) MakePathError!void
// Deletar diretório vazio
pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void
// Deletar diretório e todo seu conteúdo
pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void
Leitura Rápida
// Ler arquivo inteiro em memória (com alocação)
pub fn readFileAlloc(self: Dir, allocator: Allocator, file_path: []const u8, max_bytes: usize) ![]u8
Exemplo 1: Operações Básicas de Arquivo
const std = @import("std");
pub fn main() !void {
const cwd = std.fs.cwd();
// Criar um arquivo e escrever conteúdo
{
const file = try cwd.createFile("notas.txt", .{});
defer file.close();
try file.writeAll("Lembrete: estudar Zig hoje!\n");
try file.writeAll("Segunda nota: praticar alocadores.\n");
}
// Abrir e ler o arquivo
{
const file = try cwd.openFile("notas.txt", .{});
defer file.close();
var buf: [4096]u8 = undefined;
const n = try file.readAll(&buf);
std.debug.print("Conteúdo ({d} bytes):\n{s}\n", .{ n, buf[0..n] });
}
// Renomear
try cwd.rename("notas.txt", "notas_backup.txt");
std.debug.print("Arquivo renomeado.\n", .{});
// Limpar
try cwd.deleteFile("notas_backup.txt");
std.debug.print("Arquivo removido.\n", .{});
}
Exemplo 2: Criação e Navegação de Diretórios
const std = @import("std");
pub fn main() !void {
const cwd = std.fs.cwd();
// Criar estrutura de diretórios
try cwd.makePath("projeto/src");
try cwd.makePath("projeto/tests");
try cwd.makePath("projeto/docs");
std.debug.print("Estrutura de diretórios criada.\n", .{});
// Criar arquivos dentro da estrutura
{
const main_file = try cwd.createFile("projeto/src/main.zig", .{});
defer main_file.close();
try main_file.writeAll("pub fn main() !void {}\n");
}
{
const test_file = try cwd.createFile("projeto/tests/test_main.zig", .{});
defer test_file.close();
try test_file.writeAll("test \"básico\" { }\n");
}
// Abrir subdiretório e operar nele
var src_dir = try cwd.openDir("projeto/src", .{ .iterate = true });
defer src_dir.close();
var iter = src_dir.iterate();
std.debug.print("\nArquivos em projeto/src/:\n", .{});
while (try iter.next()) |entrada| {
std.debug.print(" {s}\n", .{entrada.name});
}
// Limpar tudo
try cwd.deleteTree("projeto");
std.debug.print("\nEstrutura removida.\n", .{});
}
Exemplo 3: Leitura de Arquivo com Alocação
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const cwd = std.fs.cwd();
// Preparar arquivo de teste
{
const f = try cwd.createFile("config.ini", .{});
defer f.close();
try f.writeAll("[geral]\nnome=MeuApp\nversao=1.0\n[banco]\nhost=localhost\nporta=5432\n");
}
// Ler arquivo inteiro
const conteudo = try cwd.readFileAlloc(allocator, "config.ini", 1024 * 1024);
defer allocator.free(conteudo);
// Processar linhas
var iter = std.mem.splitSequence(u8, conteudo, "\n");
while (iter.next()) |linha| {
if (linha.len == 0) continue;
if (linha[0] == '[') {
std.debug.print("\nSeção: {s}\n", .{linha});
} else {
std.debug.print(" {s}\n", .{linha});
}
}
try cwd.deleteFile("config.ini");
}
Padrões Comuns
Verificação de Existência de Arquivo
O Zig não tem uma função exists() dedicada. O padrão idiomático é tentar abrir:
fn arquivoExiste(caminho: []const u8) bool {
const arquivo = std.fs.cwd().openFile(caminho, .{}) catch return false;
arquivo.close();
return true;
}
Escrita Atômica
Para evitar corrupção em caso de falha, escreva em arquivo temporário e renomeie:
{
const tmp = try cwd.createFile("dados.tmp", .{});
defer tmp.close();
try tmp.writeAll(novos_dados);
}
try cwd.rename("dados.tmp", "dados.txt");
Obter Caminho Absoluto
var buf: [std.fs.max_path_bytes]u8 = undefined;
const caminho_abs = try std.fs.cwd().realpath("arquivo.txt", &buf);
std.debug.print("Caminho absoluto: {s}\n", .{caminho_abs});
Módulos Relacionados
- std.fs — Visão geral do sistema de arquivos
- std.fs.File — Tipo File e operações
- std.fs.Dir — Tipo Dir e iteração
- std.fs.path — Utilitários de caminhos
- std.io — I/O usado pelos arquivos