Escrevendo arquivos em node.js
-
21-09-2019 - |
Pergunta
Eu tenho tentado encontrar uma maneira de escrever em um arquivo ao usar o Node.js, mas sem sucesso. Como eu posso fazer isso?
Solução
Existem muitos detalhes no API do sistema de arquivos. A maneira mais comum é:
const fs = require('fs');
fs.writeFile("/tmp/test", "Hey there!", function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
Outras dicas
Atualmente, existem três maneiras de escrever um arquivo:
fs.write(fd, buffer, offset, length, position, callback
)Você precisa esperar o retorno de chamada para garantir que o buffer seja gravado no disco. Não é buffer.
fs.writeFile(filename, data, [encoding], callback)
Todos os dados devem ser armazenados ao mesmo tempo; Você não pode executar gravações sequenciais.
fs.createWriteStream(path, [options]
)Cria um
WriteStream
, o que é conveniente porque você não precisa esperar por um retorno de chamada. Mas, novamente, não é tamponado.
UMA WriteStream
, como diz o nome, é um fluxo. Um fluxo por definição é "um buffer" contendo dados que se movem em uma direção (fonte ► Destino). Mas um fluxo gravável não é necessariamente "tamponado". Um fluxo é "buffer" quando você escreve n
vezes e no momento n+1
, o fluxo envia o buffer para o kernel (porque está cheio e precisa ser lavado).
Em outras palavras: "Um buffer" é o objeto. Se "é tamponado" ou não é uma propriedade desse objeto.
Se você olhar para o código, o WriteStream
herda de um gravável Stream
objeto. Se você prestar atenção, verá como eles liberam o conteúdo; Eles não têm nenhum sistema de buffer.
Se você escrever uma string, ela é convertida em um buffer e depois enviada para a camada nativa e gravada em disco. Ao escrever strings, eles não estão preenchendo nenhum buffer. Então, se você fizer:
write("a")
write("b")
write("c")
Você está fazendo:
fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))
Isso é três chamadas para a camada de E/S. Embora você esteja usando "buffers", os dados não são bobes. Um fluxo tamponado faria: fs.write(new Buffer ("abc"))
, uma chamada para a camada de E/S.
A partir de agora, no Node.js v0.12 (versão estável anunciada em 02/06/2015) agora suporta duas funções:cork()
euncork()
. Parece que essas funções finalmente permitirão buffer/lavar as chamadas de gravação.
Por exemplo, em Java, existem algumas classes que fornecem fluxos em buffer (BufferedOutputStream
, BufferedWriter
...). Se você escrever três bytes, esses bytes serão armazenados no buffer (memória) em vez de fazer uma chamada de E/S apenas para três bytes. Quando o buffer está cheio, o conteúdo é liberado e salvo no disco. Isso melhora o desempenho.
Não estou descobrindo nada, apenas lembrando como um acesso ao disco deve ser feito.
É claro que você pode torná -lo um pouco mais avançado. Não bloqueando, escrevendo pedaços, não escrevendo o arquivo inteiro de uma só vez:
var fs = require('fs');
var stream = fs.createWriteStream("my_file.txt");
stream.once('open', function(fd) {
stream.write("My first row\n");
stream.write("My second row\n");
stream.end();
});
var path = 'public/uploads/file.txt',
buffer = new Buffer("some content\n");
fs.open(path, 'w', function(err, fd) {
if (err) {
throw 'error opening file: ' + err;
}
fs.write(fd, buffer, 0, buffer.length, null, function(err) {
if (err) throw 'error writing file: ' + err;
fs.close(fd, function() {
console.log('file written');
})
});
});
Escrita síncrona
fs.writefilesync (arquivo, dados [, opções])
fs = require('fs');
fs.writeFileSync("synchronous.txt", "synchronous write!")
Escrita assíncrona
fs.WriteFile (arquivo, dados [, opções], retorno de chamada)
fs = require('fs');
fs.writeFile('asynchronous.txt', 'asynchronous write!', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
Onde
file <string> | <Buffer> | <URL> | <integer> filename or file descriptor
data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
callback <Function>
Vale a pena ler o sistema de arquivos oficiais (FS) documentos.
eu gostei Índice de ./articles/file-system.
Funcionou para mim.
Veja também Como faço para escrever arquivos no node.js?.
fs = require('fs');
fs.writeFile('helloworld.txt', 'Hello World!', function (err) {
if (err)
return console.log(err);
console.log('Wrote Hello World in file helloworld.txt, just check it');
});
Conteúdo de helloworld.txt:
Hello World!
Atualizar:
Como no Linux Node Write no diretório atual, parece que em alguns outros não, então eu adiciono este comentário apenas para o caso:
Usando isso ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);
para chegar onde o arquivo está escrito.
Sei que a pergunta feita sobre "gravar", mas em um sentido mais geral "apêndice" pode ser útil em alguns casos, pois é fácil de usar em um loop para adicionar texto a um arquivo (se o arquivo existe ou não). Use um " n" se você deseja adicionar linhas, por exemplo:
var fs = require('fs');
for (var i=0; i<10; i++){
fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
var fs = require('fs');
fs.writeFile(path + "\\message.txt", "Hello", function(err){
if (err) throw err;
console.log("success");
});
Por exemplo: Leia o arquivo e escreva em outro arquivo:
var fs = require('fs');
var path = process.cwd();
fs.readFile(path+"\\from.txt",function(err,data)
{
if(err)
console.log(err)
else
{
fs.writeFile(path+"\\to.text",function(erro){
if(erro)
console.log("error : "+erro);
else
console.log("success");
});
}
});
As respostas fornecidas são datadas e uma maneira mais nova de fazer isso é:
const fsPromises = require('fs').promises
await fsPromises.writeFile('/path/to/file.txt', 'data to write')
Ok, é bastante simples, pois o Node possui funcionalidade integrada para isso, é chamado fs
que significa Sistema de arquivo E basicamente, Módulo de sistema de arquivos nodejs...
Então, primeiro exige isso em seu Server.js arquivo como este:
var fs = require('fs');
fs
tem poucos métodos para fazer gravar para arquivar, mas minha maneira preferida está usando appendFile
, isso anexará o material ao arquivo e, se o arquivo não existir, criará um, o código poderá ser como abaixo:
fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
if (err) throw err;
console.log('Thanks, It\'s saved to the file!');
});
Você pode escrever em um arquivo usando fs (Sistema de arquivo) Módulo.
Aqui está um exemplo de como você pode fazer isso:
const fs = require('fs');
const writeToFile = (fileName, callback) => {
fs.open(fileName, 'wx', (error, fileDescriptor) => {
if (!error && fileDescriptor) {
// Do something with the file here ...
fs.writeFile(fileDescriptor, newData, (error) => {
if (!error) {
fs.close(fileDescriptor, (error) => {
if (!error) {
callback(false);
} else {
callback('Error closing the file');
}
});
} else {
callback('Error writing to new file');
}
});
} else {
callback('Could not create new file, it may already exists');
}
});
};
Você também pode querer se livrar dessa estrutura de código de retorno-inside-lackback, usando Promessas e async
/await
declarações. Isso tornará a estrutura do código assíncrona muito mais plana. Por fazer isso, existe um prático util.promisify (original) A função pode ser utilizada. Ele nos permite mudar de retornos de chamada para promessas. Dê uma olhada no exemplo com fs
Funções abaixo:
// Dependencies.
const util = require('util');
const fs = require('fs');
// Promisify "error-back" functions.
const fsOpen = util.promisify(fs.open);
const fsWrite = util.promisify(fs.writeFile);
const fsClose = util.promisify(fs.close);
// Now we may create 'async' function with 'await's.
async function doSomethingWithFile(fileName) {
const fileDescriptor = await fsOpen(fileName, 'wx');
// Do something with the file here...
await fsWrite(fileDescriptor, newData);
await fsClose(fileDescriptor);
}
Aqui, usamos W+ para leitura/gravação de ambas as ações e se o caminho do arquivo não for encontrado, seria criado automaticamente.
fs.open(path, 'w+', function(err, data) {
if (err) {
console.log("ERROR !! " + err);
} else {
fs.write(data, 'content', 0, 'content length', null, function(err) {
if (err)
console.log("ERROR !! " + err);
fs.close(data, function() {
console.log('written success');
})
});
}
});
Conteúdo significa o que você deve escrever no arquivo e em seu comprimento, 'content.length'.
Aqui está a amostra de como ler o arquivo CSV do local e gravar arquivo CSV para local.
var csvjson = require('csvjson'),
fs = require('fs'),
mongodb = require('mongodb'),
MongoClient = mongodb.MongoClient,
mongoDSN = 'mongodb://localhost:27017/test',
collection;
function uploadcsvModule(){
var data = fs.readFileSync( '/home/limitless/Downloads/orders_sample.csv', { encoding : 'utf8'});
var importOptions = {
delimiter : ',', // optional
quote : '"' // optional
},ExportOptions = {
delimiter : ",",
wrap : false
}
var myobj = csvjson.toSchemaObject(data, importOptions)
var exportArr = [], importArr = [];
myobj.forEach(d=>{
if(d.orderId==undefined || d.orderId=='') {
exportArr.push(d)
} else {
importArr.push(d)
}
})
var csv = csvjson.toCSV(exportArr, ExportOptions);
MongoClient.connect(mongoDSN, function(error, db) {
collection = db.collection("orders")
collection.insertMany(importArr, function(err,result){
fs.writeFile('/home/limitless/Downloads/orders_sample1.csv', csv, { encoding : 'utf8'});
db.close();
});
})
}
uploadcsvModule()
fs.createWriteStream(path[,options])
options
também pode incluir umstart
opção para permitir a gravação de dados em alguma posição após o início do arquivo. Modificar um arquivo em vez de substituí -lo pode exigir umflags
Modo der+
em vez do modo padrãow
. A codificação pode ser qualquer um dos aceitos por Amortecedor.Se
autoClose
está definido como true (comportamento padrão) em'error'
ou'finish'
O descritor de arquivo será fechado automaticamente. SeautoClose
é falso, o descritor do arquivo não será fechado, mesmo que haja um erro. É responsabilidade do aplicativo fechá -lo e garantir que não haja vazamento de descritores de arquivo.Curti Readstream, E se
fd
é especificado, WRITESTREAM irá ignorar opath
argumento e usará o descritor de arquivo especificado. Isso significa que não'open'
evento será emitido.fd
deve estar bloqueando; não bloqueandofd
s deve ser passado para net.socket.Se
options
é uma string, então especifica a codificação.
Depois, lendo este longo artigo. Você deve entender como funciona. Então, aqui está um exemplo de createWriteStream()
.
/* The fs.createWriteStream() returns an (WritableStream {aka} internal.Writeable) and we want the encoding as 'utf'-8 */
/* The WriteableStream has the method write() */
fs.createWriteStream('out.txt', 'utf-8')
.write('hello world');
Você pode escrever em um arquivo pelo seguinte exemplo de código:
var data = [{'test': '123', 'test2': 'Lorem Ipsem '}];
fs.open(datapath + '/data/topplayers.json', 'wx', function(error, fileDescriptor){
if(!error && fileDescriptor){
var stringData = JSON.stringify(data);
fs.writeFile(fileDescriptor, stringData, function(error){
if(!error){
fs.close(fileDescriptor, function(error){
if(!error){
callback(false);
}else{
callback('Error in close file');
}
});
}else{
callback('Error in writing file.');
}
});
}
}
Você pode usar a biblioteca easy-file-manager
Instale primeiro do NPMnpm install easy-file-manager
Amostra para fazer upload e remover arquivos
var filemanager = require('easy-file-manager')
var path = "/public"
var filename = "test.jpg"
var data; // buffered image
filemanager.upload(path,filename,data,function(err){
if (err) console.log(err);
});
filemanager.remove(path,"aa,filename,function(isSuccess){
if (err) console.log(err);
});
Experimente o seguinte:
fs.readFile(`${__dirname}/fileName`, 'utf-8',(err, contents) => {
if (err) throw Error(err){
console.log(contents)
}
});