Como Copiar Arquivos em Zig

Como Copiar Arquivos em Zig

Copiar arquivos é uma operação fundamental em gerenciamento de dados, backups e instalação de software. Zig oferece funções na biblioteca padrão para cópia eficiente de arquivos.

Cópia Simples com copyFile

A forma mais direta de copiar um arquivo é com Dir.copyFile.

const std = @import("std");

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

    // Copiar arquivo
    try std.fs.cwd().copyFile("origem.txt", std.fs.cwd(), "destino.txt", .{});
    try stdout.print("Arquivo copiado: origem.txt -> destino.txt\n", .{});
}

Cópia Manual com Buffer

Para ter mais controle sobre o processo de cópia, leia e escreva manualmente.

const std = @import("std");

fn copiarComBuffer(origem: []const u8, destino: []const u8) !u64 {
    const arq_origem = try std.fs.cwd().openFile(origem, .{});
    defer arq_origem.close();

    const arq_destino = try std.fs.cwd().createFile(destino, .{});
    defer arq_destino.close();

    var buf: [8192]u8 = undefined;
    var total: u64 = 0;

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

    return total;
}

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

    const bytes = try copiarComBuffer("dados.bin", "dados_backup.bin");
    try stdout.print("Copiados {d} bytes\n", .{bytes});
}

Cópia com Progresso

Para arquivos grandes, mostre o progresso da cópia.

const std = @import("std");

fn copiarComProgresso(origem: []const u8, destino: []const u8) !void {
    const stdout = std.io.getStdOut().writer();

    const arq_origem = try std.fs.cwd().openFile(origem, .{});
    defer arq_origem.close();

    const stat = try arq_origem.stat();
    const tamanho_total = stat.size;

    const arq_destino = try std.fs.cwd().createFile(destino, .{});
    defer arq_destino.close();

    var buf: [32768]u8 = undefined;
    var copiados: u64 = 0;

    while (true) {
        const n = try arq_origem.read(&buf);
        if (n == 0) break;
        try arq_destino.writeAll(buf[0..n]);
        copiados += n;

        if (tamanho_total > 0) {
            const porcento = (copiados * 100) / tamanho_total;
            try stdout.print("\rCopiando... {d}% ({d}/{d} bytes)", .{
                porcento, copiados, tamanho_total,
            });
        }
    }

    try stdout.print("\rCópia concluída: {d} bytes                \n", .{copiados});
}

pub fn main() !void {
    try copiarComProgresso("arquivo_grande.dat", "arquivo_grande_copia.dat");
}

Copiar para Outro Diretório

const std = @import("std");

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

    // Garantir que o diretório destino existe
    std.fs.cwd().makePath("backup/2026") catch |err| {
        if (err != error.PathAlreadyExists) return err;
    };

    // Abrir diretório de destino
    var dir_destino = try std.fs.cwd().openDir("backup/2026", .{});
    defer dir_destino.close();

    // Copiar para o diretório de destino
    try std.fs.cwd().copyFile("dados.txt", dir_destino, "dados.txt", .{});
    try stdout.print("Arquivo copiado para backup/2026/dados.txt\n", .{});
}

Exemplo Prático: Backup com Timestamp

const std = @import("std");

fn criarBackup(allocator: std.mem.Allocator, arquivo: []const u8) ![]const u8 {
    // Obter timestamp
    const timestamp = std.time.timestamp();

    // Separar nome e extensão
    const ponto = std.mem.lastIndexOfScalar(u8, arquivo, '.') orelse arquivo.len;
    const nome = arquivo[0..ponto];
    const ext = if (ponto < arquivo.len) arquivo[ponto..] else "";

    // Criar nome do backup
    const backup_nome = try std.fmt.allocPrint(
        allocator,
        "{s}_{d}{s}",
        .{ nome, timestamp, ext },
    );

    // Copiar
    try std.fs.cwd().copyFile(arquivo, std.fs.cwd(), backup_nome, .{});

    return backup_nome;
}

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

    const backup = try criarBackup(allocator, "config.txt");
    defer allocator.free(backup);

    try stdout.print("Backup criado: {s}\n", .{backup});
}

Veja Também

Continue aprendendo Zig

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