Scrivere file in Node.js


1646

Ho provato a trovare un modo per scrivere su un file quando utilizzo Node.js, ma senza successo. Come lo posso fare?

Risposte:


2465

Ci sono molti dettagli nell'API del file system . Il modo più comune è:

const fs = require('fs');

fs.writeFile("/tmp/test", "Hey there!", function(err) {
    if(err) {
        return console.log(err);
    }
    console.log("The file was saved!");
}); 

// Or
fs.writeFileSync('/tmp/test-sync', 'Hey there!');

26
Ho testato questo script usando Node e ho provato a cambiare il percorso del file in "/ home /", ma ho riscontrato il seguente errore: { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } Come posso modificare questo script in modo che funzioni fuori /tmp?
Anderson Green,

130
Nota anche che puoi usare fs.writeFileSync (...) per realizzare la stessa cosa in modo sincrono.
David Erwin,

7
Forse è un po 'vecchio, ma @AndersonGreen, è necessario eseguire correttamente il nodo come root o chmod / home per consentire le autorizzazioni R / W all'attuale proprietario del processo del nodo (nome utente difficile) in modo da poter scrivere il file
Denys Vitali

39
In realtà, @DenysVitali, il problema è che jane non dovrebbe essere in grado di scrivere alcun file /home/.... Generalmente quella directory è 755 root: wheel (o qualunque altra cosa). Se il nodo vuole scrivere un file come jane, sarà più facile scrivere /home/jane/test.txt. Passare /homea qualcosa di più permissivo di 755 è un errore enorme.
jane arc,

7
@JaneAvriette Bene, dal momento che voleva salvare il file nella /homedirectory ho suggerito di cambiarlo. So che potrebbe generare un problema di sicurezza. Ma bene, se l'utente vuole salvare lì, questa è la soluzione. PS: sono d'accordo con quello che hai detto (:
Denys Vitali,

537

Attualmente ci sono tre modi per scrivere un file:

  1. fs.write(fd, buffer, offset, length, position, callback)

    È necessario attendere il callback per assicurarsi che il buffer sia scritto sul disco. Non è bufferizzato.

  2. fs.writeFile(filename, data, [encoding], callback)

    Tutti i dati devono essere archiviati contemporaneamente; non è possibile eseguire scritture sequenziali.

  3. fs.createWriteStream(path, [options])

    Crea un WriteStream, che è conveniente perché non è necessario attendere una richiamata. Ma ancora una volta, non è bufferizzato.

A WriteStream, come dice il nome, è un flusso. Un flusso per definizione è "un buffer" contenente dati che si muovono in una direzione (sorgente ► destinazione). Ma un flusso scrivibile non è necessariamente "bufferizzato". Uno stream viene “bufferizzato” quando si scrivono i ntempi, e alla volta n+1lo stream invia il buffer al kernel (perché è pieno e deve essere scaricato).

In altre parole: "un buffer" è l'oggetto. Se "è bufferizzato" è una proprietà di quell'oggetto.

Se guardi il codice, WriteStreameredita da un Streamoggetto scrivibile . Se presti attenzione, vedrai come svuotano il contenuto; non hanno alcun sistema di buffering.

Se scrivi una stringa, viene convertita in un buffer, quindi inviata al livello nativo e scritta su disco. Quando scrivono stringhe, non stanno riempiendo alcun buffer. Quindi, se lo fai:

write("a")
write("b")
write("c")

Stai facendo:

fs.write(new Buffer("a"))
fs.write(new Buffer("b"))
fs.write(new Buffer("c"))

Sono tre chiamate al livello I / O. Sebbene tu stia utilizzando "buffer", i dati non sono bufferizzati. Un flusso buffer farebbe:, fs.write(new Buffer ("abc"))una chiamata al livello I / O.

A partire da ora, in Node.js v0.12 (versione stabile annunciata il 02/06/2015) ora supporta due funzioni: cork()e uncork(). Sembra che queste funzioni ti consentiranno finalmente di bufferizzare / svuotare le chiamate di scrittura.

Ad esempio, in Java ci sono alcune classi che forniscono flussi bufferizzati ( BufferedOutputStream, BufferedWriter...). Se si scrivono tre byte, questi byte verranno archiviati nel buffer (memoria) invece di eseguire una chiamata I / O solo per tre byte. Quando il buffer è pieno, il contenuto viene scaricato e salvato su disco. Questo migliora le prestazioni.

Non sto scoprendo nulla, sto solo ricordando come dovrebbe essere fatto l'accesso al disco.


5
+1 - bella spiegazione. Per il flusso di scrittura, è importante leggere attentamente i documenti. Se restituisce false o closing, è importante chiamare writer.once ('drain', function () {}) oppure ho perso le righe che non erano state scaricate al termine del processo.
bryanmac,

4
qualche possibilità che potresti fornire un esempio di come utilizzare cork()e uncork()per quelli di noi che vogliono provare il nodo 0.11 pre-release?
professormeowingtons,

A partire da ora, il nodo v0.12 è stabile.
agosto

Secondo un'analisi del codice di GitHub, fs.writeFile sembra essere la più popolare delle funzioni menzionate. Ecco alcuni esempi del mondo reale per l'utilizzo di fs.writeFile
drorw,

Esistono librerie di qualità di produzione npmsull'implementazione della scrittura in buffer?
nponeccop,

266

Ovviamente puoi renderlo un po 'più avanzato. Non bloccando, scrivendo bit e pezzi, non scrivendo l'intero file in una volta:

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();
});

17
Qual è la variabile 'fd' passata nel callback per stream.once?
Scott Tesler,

1
Descrittore di file @ScottDavidTesler in modo da poter chiudere lo streaming dopo averlo fatto.
Alexey Kamenskiy,

3
Quando chiudo il flusso? Perché questo non blocca? Solo curioso, sto cercando di scrivere su un file di registro.
MetaGuru

1
Non sono sicuro se quando il flusso viene scaricato. La mia ipotesi è che esiste la possibilità di svuotare il flusso su richiesta.
Fredrik Andersson,

1
@JoLiss Dovrai aspettare.
Fredrik Andersson,

61

Scrittura sincrona

fs.writeFileSync (file, data [, opzioni])

fs = require('fs');

fs.writeFileSync("synchronous.txt", "synchronous write!")

Scrittura asincrona

fs.writeFile (file, data [, opzioni], callback)

fs = require('fs');

fs.writeFile('asynchronous.txt', 'asynchronous write!', (err) => {
  if (err) throw err;
  console.log('The file has been saved!');
});

Dove

file <string> | <Buffer> | <URL> | <integer> filename or file descriptor
data <string> | <Buffer> | <Uint8Array>
options <Object> | <string>
callback <Function>

La pena di leggere il file di sistema ufficiale (fs) docs .


53
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');
        })
    });
});

2
questo dimostra come scrivere un file usando operazioni fs di livello inferiore. ad esempio, puoi garantire quando il file ha finito di scrivere su disco e ha rilasciato i descrittori di file.
Sean Glover,

Poiché in questo esempio l'offset è impostato su '0' (= terzo parametro di fs.write()) questo esempio funziona solo se tutto è abbastanza corto per essere scritto in una singola chiamata di scrittura.
Manfred

31

Mi è piaciuto l' indice di ./articles/file-system .

Ha funzionato per me.

Vedi anche Come scrivo i file in 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');
});

Contenuti di helloworld.txt:

Hello World!

Aggiornamento:
Come nel nodo Linux scrivi nella directory corrente, sembra che in alcuni altri no, quindi aggiungo questo commento nel caso in cui:
Usando questo ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);per ottenere dove è scritto il file.


Dove trovare il file helloworld.txt? Non riesco a trovarlo in nessuna cartella ... grazie.
Kai Feng Chew,

nella cartella in cui esegui la sceneggiatura
Sérgio

È strano ... Non riesco a trovarlo da nessuna parte. Sarà nascosto? grazie ancora ~
Kai Feng Chew il

6
L'ho appena trovato. Utilizzando questo ROOT_APP_PATH = fs.realpathSync ('.'); console.log ( ROOT_APP_PATH ); per ottenere il mio dove il file scritto. Grazie.
Kai Feng Chew

@Sérgio: dobbiamo chiudere writefile? Sto chiamando un altro processo e ricevo un messaggio di errore relativo al file che viene utilizzato da qualche altro processo.
Amir

24

Le risposte fornite sono datate e un modo più nuovo per farlo è:

const fsPromises = require('fs').promises
await fsPromises.writeFile('/path/to/file.txt', 'data to write')

vedere i documenti qui per maggiori informazioni


1
(node:23759) ExperimentalWarning: The fs.promises API is experimental
jgraup

@jgraup: stai usando l'ultima versione di nodo?
TrevTheDev,

Nodov10.15.0
jgraup

7
La funzione di chiusura deve essere asincrona o non funzionerà.
Zimano,

1
@wintercounter È abbastanza dolce!
Zimano,

19

So che la domanda posta su "scrivere", ma in senso più generale, "append" potrebbe essere utile in alcuni casi in quanto è facile da usare in un ciclo per aggiungere testo a un file (indipendentemente dal fatto che il file esista o meno). Utilizzare un "\ n" se si desidera aggiungere righe, ad esempio:

var fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}

Dato che è ora disponibile, consiglierei di utilizzare constinvece di var, ad esempio const fs = require('fs');, per evitare effetti collaterali indesiderati, in particolare se stai lavorando con una base di codice un po 'più grande.
Manfred

11

OK, è abbastanza semplice in quanto Node ha funzionalità integrate per questo, si chiama fsche sta per File System e fondamentalmente, modulo NodeJS File System ...

Quindi prima richiedilo nel tuo file server.js in questo modo:

var fs = require('fs');

fsha pochi metodi per scrivere su file, ma il mio modo preferito è usare appendFile, questo aggiungerà le cose al file e se il file non esiste, ne creerà uno, il codice potrebbe essere come di seguito:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});

3
la singola virgoletta nella stringa deve essere sfuggita.
Tamer,

9
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Ad esempio: leggi il file e scrivi su un altro file:

  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");
                            });
                        }
                });

Dove stai scrivendo i dati nel "to.text" ??
Ravi Shanker Reddy,

Cosa aggiunge questa risposta alle molteplici risposte già esistenti writeFile?
Dan Dascalescu,

9

È possibile scrivere su un file usando il modulo fs (file system).

Ecco un esempio di come puoi farlo:

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');
    }
  });
};

Potresti anche voler sbarazzarti di questa struttura di codice callback-inside-callback usando Promises e async/ awaitdichiarazioni. Ciò renderà la struttura del codice asincrono molto più piatta. Per fare ciò, è possibile utilizzare una utile funzione util.promisify (originale) . Ci consente di passare da callback a promesse. Dai un'occhiata all'esempio con le fsfunzioni seguenti:

// 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);
}

1
Perché questi frammenti e non pezzi di codice? Non saranno comunque in grado di funzionare in un browser.
Zimano,

@Zimano A quanto ho capito, la domanda riguardava nodejs, quindi non è necessario essere in grado di funzionare in un browser.
Manfred

1
@Manfred Exactly! Penso che tu abbia frainteso quello che stavo cercando di dire; non ha senso avere frammenti poiché è nodejs!
Zimano,

5

Qui usiamo w + per leggere / scrivere entrambe le azioni e se il percorso del file non viene trovato, verrebbe creato 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');
            })
        });
    }
});

Contenuto indica ciò che devi scrivere nel file e la sua lunghezza, "content.length".


3

Ecco l'esempio di come leggere il file CSV da locale e scrivere il file CSV in locale.

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()

1
Questo introduce ogni sorta di complicazioni (MongoClient, JSON ecc.) Che non riguardano la domanda.
Dan Dascalescu,

3

fs.createWriteStream(path[,options])

optionspuò anche includere startun'opzione per consentire la scrittura di dati in una certa posizione oltre l'inizio del file. La modifica di un file anziché la sua sostituzione potrebbe richiedere una flagsmodalità r+anziché la modalità predefinita w. La codifica può essere una di quelle accettate da Buffer .

Se autoCloseè impostato su true (comportamento predefinito) 'error'o 'finish'il descrittore di file verrà chiuso automaticamente. Se autoCloseè falso, il descrittore di file non verrà chiuso, anche se si verifica un errore. È responsabilità dell'applicazione chiuderlo e assicurarsi che non vi siano perdite dal descrittore di file.

Come ReadStream , se fdspecificato, WriteStream ignorerà l' pathargomento e utilizzerà il descrittore di file specificato. Ciò significa che non 'open'verrà emesso alcun evento. fddovrebbe bloccare; i messaggi non bloccanti fddevono essere passati a net.Socket .

Se optionsè una stringa, specifica la codifica.

Dopo, leggendo questo lungo articolo. Dovresti capire come funziona. Quindi, ecco un esempio di 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');

createWriteStreamera già stato menzionato in risposte multiple anni prima di questo.
Dan Dascalescu,

0

Puoi usare la libreria easy-file-manager

installa prima da npm npm install easy-file-manager

Esempio per caricare e rimuovere file

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);
});

2
This modules is created to save and remove files.. Non una risposta
Verde,

-1

È possibile scrivere in un file con il seguente esempio di codice:

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.');
      }
    });
  }
});

1
writeFileera già stata data più volte una risposta, anni fa. Cosa aggiunge questa risposta?
Dan Dascalescu,

Anche perché apri il file? La risposta non dovrebbe riguardare la scrittura di file?
Michal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.