Como append um arquivo no Node?

Eu estou tentando acrescentar uma seqüência de caracteres a um arquivo de log. No entanto writeFile irá apagar o conteúdo de cada vez antes de escrever a string.

fs.writeFile('log.txt', 'Hello Node', function (err) { if (err) throw err; console.log('It\'s saved!'); }); // => message.txt erased, contains only 'Hello Node' 

Alguma idéia de como fazer isso da maneira mais fácil?

Daniel

Para anexos ocasionais, você pode usar appendFile , que cria um novo identificador de arquivo sempre que for chamado:

Assincronamente :

 const fs = require('fs'); fs.appendFile('message.txt', 'data to append', function (err) { if (err) throw err; console.log('Saved!'); }); 

Sincronicamente :

 const fs = require('fs'); fs.appendFileSync('message.txt', 'data to append'); 

Mas se você append repetidamente ao mesmo arquivo, é muito melhor reutilizar o identificador de arquivo .

Seu código usando createWriteStream cria um descritor de arquivo para cada gravação. log.end é melhor porque pede nó para fechar imediatamente após a gravação.

 var fs = require('fs'); var logStream = fs.createWriteStream('log.txt', {'flags': 'a'}); // use {'flags': 'a'} to append and {'flags': 'w'} to erase and write a new file logStream.write('Initial line...'); logStream.end('this is the end line'); 

Quando você deseja gravar em um arquivo de log, ou seja, append dados ao final de um arquivo, nunca usa appendFile , appendFile abre um identificador de arquivo para cada parte dos dados adicionados ao arquivo, depois de um tempo você obtém um belo erro EMFILE .

Eu posso adicionar que appendFile não é mais fácil de usar do que um WriteStream .

Exemplo com appendFile :

 console.log(new Date().toISOString()); [...Array(10000)].forEach( function (item,index) { fs.appendFile("append.txt", index+ "\n", function (err) { if (err) console.log(err); }); }); console.log(new Date().toISOString()); 

Até 8000 no meu computador, você pode acrescentar dados ao arquivo, então você obtém isto:

 { Error: EMFILE: too many open files, open 'C:\mypath\append.txt' at Error (native) errno: -4066, code: 'EMFILE', syscall: 'open', path: 'C:\\mypath\\append.txt' } 

Além disso, o appendFile irá escrever quando estiver habilitado, para que seus registros não sejam gravados pelo timestamp. Você pode testar com o exemplo, definir 1000 no lugar de 100.000, a ordem será aleatória, depende do access ao arquivo.

Se você quiser append a um arquivo, você deve usar um stream gravável como este:

 var stream = fs.createWriteStream("append.txt", {flags:'a'}); console.log(new Date().toISOString()); [...Array(10000)].forEach( function (item,index) { stream.write(index + "\n"); }); console.log(new Date().toISOString()); stream.end(); 

Você termina quando quiser. Você nem precisa usar o stream.end() , a opção padrão é AutoClose:true , então seu arquivo terminará quando o processo terminar e você evitar abrir muitos arquivos.

Você precisa abri-lo e depois escrever para ele.

 var fs = require('fs'), str = 'string to append to file'; fs.open('filepath', 'a', 666, function( e, id ) { fs.write( id, 'string to append to file', null, 'utf8', function(){ fs.close(id, function(){ console.log('file closed'); }); }); }); 

Aqui estão alguns links que ajudarão a explicar os parâmetros

aberto
Escreva
fechar


EDIT : Esta resposta não é mais válida, examine o novo método fs.appendFile para append.

Além de appendFile , você também pode passar um sinalizador em writeFile para append dados a um arquivo existente.

 fs.writeFile('log.txt', 'Hello Node', {'flag':'a'}, function(err) { if (err) { return console.error(err); } }); 

Ao passar o sinalizador ‘a’, os dados serão anexados no final do arquivo.

O nó 0.8 possui fs.appendFile :

 fs.appendFile('message.txt', 'data to append', function (err) { if (err) throw err; console.log('The "data to append" was appended to file!'); }); 

Documentos: http://nodejs.org/docs/latest/api/fs.html#fs_fs_appendfile_filename_data_encoding_utf8_callback

 fd = fs.openSync(path.join(process.cwd(), 'log.txt'), 'a') fs.writeSync(fd, 'contents to append') fs.closeSync(fd) 

Usando o pacote jfile :

 myFile.text+='\nThis is new line to be appended'; //myFile=new JFile(path); 

Eu ofereço esta sugestão somente porque o controle sobre flags abertos é às vezes útil, por exemplo, você pode querer truncar um arquivo existente primeiro e depois acrescentar uma série de escritas a ele – nesse caso use o sinalizador ‘w’ ao abrir o arquivo e não feche até que todas as gravações estejam concluídas. Claro appendFile pode ser o que você está depois 🙂

  fs.open('log.txt', 'a', function(err, log) { if (err) throw err; fs.writeFile(log, 'Hello Node', function (err) { if (err) throw err; fs.close(log, function(err) { if (err) throw err; console.log('It\'s saved!'); }); }); }); 

Se você quiser uma maneira fácil e livre de estresse para gravar logs linha por linha em um arquivo, então eu recomendo o fs-extra :

 const os = require('os'); const fs = require('fs-extra'); const file = 'logfile.txt'; const options = {flag: 'a'}; async function writeToFile(text) { await fs.outputFile(file, `${text}${os.EOL}`, options); } writeToFile('First line'); writeToFile('Second line'); writeToFile('Third line'); writeToFile('Fourth line'); writeToFile('Fifth line'); 

Testado com o Nó v8.9.4.

Aqui está um roteiro completo. Preencha seus nomes de arquivo e execute-o e ele deve funcionar! Aqui está um tutorial em vídeo sobre a lógica por trás do script.

 var fs = require('fs'); function ReadAppend(file, appendFile){ fs.readFile(appendFile, function (err, data) { if (err) throw err; console.log('File was read'); fs.appendFile(file, data, function (err) { if (err) throw err; console.log('The "data to append" was appended to file!'); }); }); } // edit this with your file names file = 'name_of_main_file.csv'; appendFile = 'name_of_second_file_to_combine.csv'; ReadAppend(file, appendFile); 

uma maneira mais fácil de fazer isso é

 const fs = require('fs'); fs.appendFileSync('file.txt', 'message to append into file');