Trabalho com o sistema de arquivos em C++: do básico às técnicas avançadas
Trabalhar com o sistema de arquivos é uma das tarefas principais em qualquer aplicação séria em C++. Seja lendo arquivos de configuração, escrevendo logs, processando grandes volumes de dados ou gerenciando projetos — saber interagir corretamente com arquivos e diretórios é necessário para todo desenvolvedor C++. Neste artigo, vamos abordar as principais abordagens para trabalhar com o sistema de arquivos em C++, desde as funções clássicas da linguagem C até o moderno std::filesystem, introduzido no C++17.
Vamos examinar exemplos práticos que ajudarão você não apenas a entender a teoria, mas também a aplicar imediatamente o conhecimento adquirido em projetos reais. Todos os exemplos de código foram testados e estão prontos para uso.
1. Fundamentos do trabalho com arquivos: fluxos de entrada/saída
A forma mais comum de trabalhar com arquivos em C++ é usando a biblioteca <fstream>. Ela fornece três classes principais:
std::ifstream— para leitura de arquivo (input file stream);std::ofstream— para escrita em arquivo (output file stream);std::fstream— para leitura e escrita (file stream).
Leitura de arquivo
Para ler dados de um arquivo, crie um objeto std::ifstream e abra o arquivo. A maneira mais simples de ler um arquivo linha por linha é usar a função std::getline:
#include <iostream>#include <fstream>#include <string>
int main() { std::ifstream inputFile("example.txt"); if (!inputFile.is_open()) { std::cerr << "Erro ao abrir o arquivo!" << std::endl; return 1; }
std::string line; while (std::getline(inputFile, line)) { std::cout << line << std::endl; }
inputFile.close(); return 0;}Observe a verificação is_open() — esta é uma prática importante que evita que o programa quebre quando o arquivo não existe.
Escrita em arquivo
Para escrever dados, usa-se std::ofstream. Por padrão, o arquivo é criado novamente (modo trunc). Se precisar adicionar dados ao final, use a flag std::ios::app:
#include <iostream>#include <fstream>
int main() { std::ofstream outputFile("output.txt", std::ios::app); if (!outputFile.is_open()) { std::cerr << "Erro ao criar o arquivo!" << std::endl; return 1; }
outputFile << "Linha 1" << std::endl; outputFile << "Linha 2" << std::endl; outputFile << "Número: " << 42 << std::endl;
outputFile.close(); return 0;}Trabalho com arquivos binários
Para dados binários, use os métodos read() e write() especificando o tamanho do bloco:
#include <iostream>#include <fstream>#include <cstring>
struct Record { int id; char name[50]; double value;};
int main() { // Escrita Record r = {1, "Registro de teste", 3.14}; std::ofstream binOut("data.bin", std::ios::binary); binOut.write(reinterpret_cast<const char*>(&r), sizeof(r)); binOut.close();
// Leitura Record r2; std::ifstream binIn("data.bin", std::ios::binary); binIn.read(reinterpret_cast<char*>(&r2), sizeof(r2)); binIn.close();
std::cout << "ID: " << r2.id << ", Name: " << r2.name << ", Value: " << r2.value << std::endl; return 0;}2. Abordagem moderna: biblioteca std::filesystem (C++17)
A partir do C++17, a biblioteca padrão recebeu <filesystem>, que simplifica significativamente o trabalho com o sistema de arquivos. O