Introdução: Por que saber trabalhar com arquivos em JavaScript?
\n\nQuando falamos de JavaScript, a maioria lembra imediatamente do navegador e de interfaces interativas. No entanto, com o surgimento da plataforma Node.js, o JavaScript foi muito além das páginas web. Hoje, é uma linguagem completa para desenvolvimento de servidores, automação e utilitários. E uma das tarefas essenciais que todo desenvolvedor enfrenta é trabalhar com o sistema de arquivos.
\n\nSaber ler, escrever, mover e excluir arquivos é o básico, sem o qual nenhum projeto sério pode ser imaginado. Seja um logger, um arquivo de configuração, upload de imagens ou análise de dados — em todos os lugares é necessário acesso ao sistema de arquivos.
\n\nNeste artigo, vamos explorar exemplos práticos de trabalho com o sistema de arquivos no Node.js. Você aprenderá como usar o módulo embutido fs, quais métodos existem e como evitar erros comuns. Todo o código pode ser executado e testado imediatamente.
Métodos principais do módulo fs
\n\nO módulo fs (File System) faz parte da instalação padrão do Node.js. Não é necessário instalá-lo separadamente. Para começar, basta importá-lo no início do arquivo:
const fs = require('fs');\nconst fsPromises = require('fs').promises; // para trabalhar com promises\n\nTodos os métodos do módulo fs existem em três variações:
- \n
- Síncronos — bloqueiam a execução do código até a conclusão da operação. Geralmente têm o sufixo
Sync. \n - Assíncronos com callbacks — estilo clássico do Node.js. \n
- Assíncronos com promises — abordagem moderna através de
fs.promises. \n
Em projetos modernos, recomenda-se usar promises e async/await. Isso torna o código mais limpo e compreensível.
Leitura de arquivos
\n\nO cenário mais comum é ler o conteúdo de um arquivo. Vejamos um exemplo com o arquivo de texto data.txt:
const fs = require('fs').promises;\n\nasync function readFileExample() {\n try {\n const data = await fs.readFile('data.txt', 'utf8');\n console.log('Conteúdo do arquivo:');\n console.log(data);\n } catch (err) {\n console.error('Erro ao ler o arquivo:', err.message);\n }\n}\n\nreadFileExample();\n\nO segundo parâmetro 'utf8' especifica a codificação. Se for omitido, você obterá um buffer bruto (Buffer). Para arquivos de texto, sempre especifique a codificação.
Escrita em arquivo
\n\nA gravação de dados em um arquivo pode ser feita de duas maneiras: substituição completa ou adição ao final.
\n\nSubstituição do arquivo:
\nconst fs = require('fs').promises;\n\nasync function writeFileExample() {\n try {\n await fs.writeFile('output.txt', 'Olá, sistema de arquivos!');\n console.log('Arquivo escrito com sucesso');\n } catch (err) {\n console.error('Erro ao escrever:', err.message);\n }\n}\n\nwriteFileExample();\n\nAdição ao final do arquivo:
\nconst fs = require('fs').promises;\n\nasync function appendFileExample() {\n try {\n await fs.appendFile('log.txt', `Nova entrada: ${new Date().toISOString()}\\n`);\n console.log('Dados adicionados');\n } catch (err) {\n console.error('Erro ao adicionar:', err.message);\n }\n}\n\nappendFileExample();\n\nO método appendFile é ideal para manter logs ou acumular dados.
Gerenciamento de diretórios e arquivos
\n\nTrabalhar com o sistema de arquivos não se limita à leitura e escrita. Frequentemente, é necessário criar pastas, verificar a existência de arquivos ou excluí-los.
\n\nCriação e exclusão de diretórios
\n\nconst fs = require('fs').promises;\n\nasync function manageDirectories() {\n try {\n // Criação de diretório (se não existir)\n await fs.mk