Schreiben von Dateien in Node.js.

1646

Ich habe versucht, einen Weg zu finden, um mit Node.js in eine Datei zu schreiben, aber ohne Erfolg. Wie kann ich das machen?

Gjorgji
quelle

Antworten:

2465

Die Dateisystem-API enthält viele Details . Der häufigste Weg ist:

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!');
Brian McKenna
quelle
26
Ich habe dieses Skript mit Node getestet und versucht, den Dateipfad in "/ home /" zu { [Error: EACCES, open '/home/test.txt'] errno: 3, code: 'EACCES', path: '/home/test.txt' } ändern. Es wurde jedoch der folgende Fehler angezeigt: Wie kann ich dieses Skript so ändern, dass es außerhalb von funktioniert /tmp?
Anderson Green
130
Beachten Sie auch, dass Sie fs.writeFileSync (...) verwenden können, um dasselbe synchron auszuführen.
David Erwin
7
Vielleicht ist es ein bisschen alt, aber @AndersonGreen, Sie müssen den Knoten ordnungsgemäß als root oder chmod / home ausführen, um dem aktuellen Eigentümer des Knotenprozesses R / W-Berechtigungen zu gewähren (Ihr Benutzername ist schwierig), damit Sie die Datei schreiben können
Denys Vitali
39
Eigentlich, @DenysVitali, ist das Problem, dass Jane keine Dateien schreiben kann /home/.... Im Allgemeinen ist dieses Verzeichnis 755 root: radius (oder was auch immer). Wenn der Knoten eine Datei als Jane schreiben möchte, ist das Schreiben einfacher /home/jane/test.txt. Es /homeist ein großer Fehler, zu etwas Zulässigerem als 755 zu wechseln .
Jane Arc
7
@ JaneAvriette Nun, da er die Datei im /homeVerzeichnis speichern wollte, schlug ich vor, sie zu ändern. Ich weiß, dass dies zu einem Sicherheitsproblem führen kann. Aber wenn der Benutzer dort speichern möchte, ist dies die Lösung. PS: Ich stimme dem zu, was Sie gesagt haben (:
Denys Vitali
537

Derzeit gibt es drei Möglichkeiten, eine Datei zu schreiben:

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

    Sie müssen auf den Rückruf warten, um sicherzustellen, dass der Puffer auf die Festplatte geschrieben wird. Es ist nicht gepuffert.

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

    Alle Daten müssen gleichzeitig gespeichert werden. Sie können keine sequentiellen Schreibvorgänge ausführen.

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

    Erstellt eine WriteStream, was praktisch ist, da Sie nicht auf einen Rückruf warten müssen. Aber auch hier ist es nicht gepuffert.

A ist WriteStream, wie der Name schon sagt, ein Stream. Ein Stream ist per Definition „ein Puffer“, der Daten enthält, die sich in eine Richtung bewegen (Quelle ► Ziel). Ein beschreibbarer Stream ist jedoch nicht unbedingt „gepuffert“. Ein Stream wird beim Schreiben "gepuffert" n, und zur Zeit n+1sendet der Stream den Puffer an den Kernel (weil er voll ist und geleert werden muss).

Mit anderen Worten: "Ein Puffer" ist das Objekt. Ob es "gepuffert" ist oder nicht, ist eine Eigenschaft dieses Objekts.

Wenn Sie sich den Code ansehen, WriteStreamerbt er von einem beschreibbaren StreamObjekt. Wenn Sie darauf achten, werden Sie sehen, wie sie den Inhalt spülen. Sie haben kein Puffersystem.

Wenn Sie eine Zeichenfolge schreiben, wird diese in einen Puffer konvertiert, dann an die native Ebene gesendet und auf die Festplatte geschrieben. Beim Schreiben von Strings füllen sie keinen Puffer. Wenn Sie dies tun:

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

Sie gehen:

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

Das sind drei Aufrufe an die E / A-Schicht. Obwohl Sie "Puffer" verwenden, werden die Daten nicht gepuffert. Ein gepufferter Stream würde ausreichen: fs.write(new Buffer ("abc"))Ein Aufruf der E / A-Schicht.

Ab sofort unterstützt Node.js v0.12 (stabile Version angekündigt 02/06/2015) jetzt zwei Funktionen: cork()und uncork(). Es scheint, dass Sie mit diesen Funktionen endlich die Schreibaufrufe puffern / leeren können.

In Java gibt es beispielsweise einige Klassen, die gepufferte Streams ( BufferedOutputStream, BufferedWriter...) bereitstellen . Wenn Sie drei Bytes schreiben, werden diese Bytes im Puffer (Speicher) gespeichert, anstatt nur für drei Bytes einen E / A-Aufruf durchzuführen. Wenn der Puffer voll ist, wird der Inhalt geleert und auf der Festplatte gespeichert. Dies verbessert die Leistung.

Ich entdecke nichts, erinnere mich nur daran, wie ein Festplattenzugriff erfolgen sollte.

Gabriel Llamas
quelle
5
+1 - nette Erklärung. Für den Schreibstrom ist es wichtig, die Dokumente sorgfältig zu lesen. Wenn false oder Closing zurückgegeben wird, ist es wichtig, writer.once ('drain', function () {}) aufzurufen, oder ich habe Zeilen übersehen, die am Ende des Prozesses nicht abgelassen wurden.
Bryanmac
4
Gibt es eine Möglichkeit, ein Beispiel für die Verwendung cork()und uncork()für diejenigen von uns zu geben, die den Knoten vor der Version 0.11 ausprobieren möchten?
Professor
Ab sofort ist Node v0.12 stabil.
August
Laut einer Analyse des Codes von GitHub scheint fs.writeFile die beliebteste der von Ihnen erwähnten Funktionen zu sein. Hier sind Beispiele aus der Praxis für die Verwendung von fs.writeFile
drorw
Gibt es Bibliotheken mit Produktionsqualität für die npmImplementierung von gepuffertem Schreiben?
Nponeccop
266

Sie können es natürlich etwas fortgeschrittener machen. Nicht blockieren, Kleinigkeiten schreiben, nicht die gesamte Datei auf einmal schreiben:

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();
});
Fredrik Andersson
quelle
17
Was ist die Variable 'fd', die an den Rückruf für stream.once übergeben wird?
Scott Tesler
1
@ScottDavidTesler-Dateideskriptor, damit Sie den Stream schließen können, nachdem Sie damit fertig sind.
Alexey Kamenskiy
3
Wann schließe ich den Stream? Warum ist das nicht blockierend? Nur neugierig, ich versuche in eine Protokolldatei zu schreiben.
MetaGuru
1
Ich bin nicht sicher, ob der Stream geleert wird. Ich vermute, dass es eine Möglichkeit gibt, den Stream bei Bedarf zu spülen.
Fredrik Andersson
1
@ JoLiss Du musst darauf warten.
Fredrik Andersson
61

Synchrones Schreiben

fs.writeFileSync (Datei, Daten [, Optionen])

fs = require('fs');

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

Asynchrones Schreiben

fs.writeFile (Datei, Daten [, Optionen], Rückruf)

fs = require('fs');

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

Wo

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

Es lohnt sich, die offiziellen Dokumente zum Dateisystem (fs) zu lesen .

Moriarty
quelle
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');
        })
    });
});
Herr P.
quelle
2
Dies zeigt, wie eine Datei mit fs-Operationen niedrigerer Ebene geschrieben wird. Sie können beispielsweise garantieren, dass die Datei das Schreiben auf die Festplatte abgeschlossen und Dateideskriptoren freigegeben hat.
Sean Glover
Da in diesem Beispiel der Offset auf '0' (= dritter Parameter von fs.write()) gesetzt ist, funktioniert dieses Beispiel nur, wenn alles kurz genug ist, um in einem einzigen Schreibaufruf geschrieben zu werden.
Manfred
31

Ich mochte Index of ./articles/file-system .

Es hat bei mir funktioniert.

Siehe auch Wie schreibe ich Dateien 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');
});

Inhalt von helloworld.txt:

Hello World!

Update:
Wie beim Schreiben von Linux-Knoten in das aktuelle Verzeichnis scheint dies bei einigen anderen nicht der Fall zu sein. Daher füge ich diesen Kommentar nur für den Fall hinzu:
Verwenden Sie diese Option ROOT_APP_PATH = fs.realpathSync('.'); console.log(ROOT_APP_PATH);, um zu ermitteln, wo die Datei geschrieben wird.

Sérgio
quelle
Wo finde ich die Datei helloworld.txt? Ich kann es in keinem Ordner finden ... danke.
Kai Feng Chew
in Ordner, in dem Sie das Skript ausführen
Sérgio
Das ist komisch ... ich kann es einfach nirgendwo finden. Wird es versteckt sein?
Kai Feng Chew
6
Ich habe es gerade gefunden. Verwenden dieser ROOT_APP_PATH = fs.realpathSync ('.'); console.log ( ROOT_APP_PATH ); um meine wo die Datei geschrieben zu bekommen. Vielen Dank.
Kai Feng Chew
@ Sérgio: Müssen wir die Schreibdatei schließen? Ich rufe einen anderen Prozess auf und erhalte eine Fehlermeldung bezüglich der Datei, die von einem anderen Prozess verwendet wird.
Amir
24

Die Antworten sind veraltet und ein neuerer Weg, dies zu tun, ist:

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

Weitere Informationen finden Sie in den Dokumenten hier

TrevTheDev
quelle
1
(node:23759) ExperimentalWarning: The fs.promises API is experimental
Jgraup
@jgraup: Verwenden Sie die neueste Version von Node?
TrevTheDev
Knotenv10.15.0
jgraup
7
Die Gehäusefunktion muss asynchron sein, sonst funktioniert dies nicht.
Zimano
1
@wintercounter Das ist ziemlich süß!
Zimano
19

Ich kenne die Frage nach "Schreiben", aber im Allgemeinen kann "Anhängen" in einigen Fällen nützlich sein, da es einfach ist, in einer Schleife Text zu einer Datei hinzuzufügen (unabhängig davon, ob die Datei vorhanden ist oder nicht). Verwenden Sie ein "\ n", wenn Sie Zeilen hinzufügen möchten, z.

var fs = require('fs');
for (var i=0; i<10; i++){
    fs.appendFileSync("junk.csv", "Line:"+i+"\n");
}
Astra Bär
quelle
Da es nun verfügbar ist würde ich recommmend mit conststatt var, das heißt const fs = require('fs');, unerwünschte Nebenwirkungen zu vermeiden, insbesondere , wenn Sie mit einer etwas größeren Codebasis arbeiten.
Manfred
11

OK, es ist ganz einfach , wie Knoten hat eingebaute Funktionalität für diese, es heißt , fsdas steht für File System und im Grunde NodeJS File System - Modul ...

Fordern Sie es also zuerst in Ihrer server.js- Datei wie folgt an :

var fs = require('fs');

fsEs gibt nur wenige Methoden zum Schreiben in eine Datei, aber meine bevorzugte Methode ist die Verwendung. Dadurch wird appendFiledas Material an die Datei angehängt. Wenn die Datei nicht vorhanden ist, wird eine erstellt. Der Code könnte wie folgt aussehen:

fs.appendFile('myFile.txt', 'Hi Ali!', function (err) {
  if (err) throw err;
  console.log('Thanks, It\'s saved to the file!');
});
Alireza
quelle
3
Ein einfaches Anführungszeichen in der Zeichenfolge sollte maskiert werden.
Tamer
9
 var fs = require('fs');
 fs.writeFile(path + "\\message.txt", "Hello", function(err){
 if (err) throw err;
  console.log("success");
}); 

Zum Beispiel: Datei lesen und in eine andere Datei schreiben:

  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");
                            });
                        }
                });
Masoud Siahkali
quelle
Wo schreiben Sie die Daten in den "to.text"?
Ravi Shanker Reddy
Was fügt diese Antwort zu den mehreren bereits vorhandenen Antworten hinzu writeFile?
Dan Dascalescu
9

Sie können mit dem Modul fs (Dateisystem) in eine Datei schreiben .

Hier ist ein Beispiel, wie Sie es tun können:

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

Möglicherweise möchten Sie diese Callback-Inside-Callback-Codestruktur auch mithilfe von Promises und async/ -Anweisungen entfernen await. Dadurch wird die asynchrone Codestruktur viel flacher. Dazu gibt es eine praktische util.promisify (Original) -Funktion. Es ermöglicht uns, von Rückrufen zu Versprechungen zu wechseln. Schauen Sie sich das Beispiel mit den folgenden fsFunktionen an:

// 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);
}
Oleksii Trekhleb
quelle
1
Warum sind diese Schnipsel und keine Codeteile? Sie können sowieso nie in einem Browser ausgeführt werden.
Zimano
@Zimano Soweit ich weiß, betraf die Frage NodeJS und muss daher nicht in einem Browser ausgeführt werden können.
Manfred
1
@Manfred Genau! Ich glaube, Sie haben falsch verstanden, was ich sagen wollte. Es macht keinen Sinn, Schnipsel zu haben, da es sich um NodeJS handelt!
Zimano
5

Hier verwenden wir w + zum Lesen / Schreiben beider Aktionen. Wenn der Dateipfad nicht gefunden wird, wird er automatisch erstellt.

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

Inhalt bedeutet, was Sie in die Datei schreiben müssen, und deren Länge "content.length".

Gunjan Patel
quelle
3

Hier ist das Beispiel, wie man eine CSV-Datei von lokal liest und eine CSV-Datei in eine lokale Datei schreibt.

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()
KARTHIKEYAN.A
quelle
1
Dies führt zu allen möglichen Komplikationen (MongoClient, JSON usw.), die sich nicht auf die Frage beziehen.
Dan Dascalescu
3

fs.createWriteStream(path[,options])

optionskann auch eine startOption enthalten, mit der Daten an einer Position nach dem Dateianfang geschrieben werden können. Das Ändern einer Datei anstelle des Ersetzens erfordert möglicherweise einen flagsModus r+anstelle des Standardmodus w. Die Codierung kann eine von Buffer akzeptierte sein .

Wenn autoCloseauf true (Standardverhalten) eingestellt ist auf 'error'oder 'finish'der Dateideskriptor wird automatisch geschlossen. Wenn autoClosefalse ist, wird der Dateideskriptor nicht geschlossen, selbst wenn ein Fehler vorliegt. Es liegt in der Verantwortung der Anwendung, sie zu schließen und sicherzustellen, dass kein Dateideskriptorleck vorliegt.

Wenn ReadStream wie angegebenfd angegeben ist, ignoriert WriteStream das pathArgument und verwendet den angegebenen Dateideskriptor. Dies bedeutet, dass kein 'open'Ereignis ausgegeben wird. fdsollte blockieren; Nicht blockierende fds sollten an net.Socket übergeben werden .

Wenn optionses sich um eine Zeichenfolge handelt, wird die Codierung angegeben.

Lesen Sie anschließend diesen langen Artikel. Sie sollten verstehen, wie es funktioniert. Hier ist ein Beispiel für 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');

quelle
createWriteStreamwurde bereits in mehreren Antwortjahren vor dieser erwähnt.
Dan Dascalescu
0

Sie können die Bibliothek verwenden easy-file-manager

zuerst von npm installieren npm install easy-file-manager

Beispiel zum Hochladen und Entfernen von Dateien

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);
});
Christoper
quelle
2
This modules is created to save and remove files.. Keine Antwort.
Grün
-1

Sie können anhand des folgenden Codebeispiels in eine Datei schreiben:

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.');
      }
    });
  }
});
Mudassir
quelle
1
writeFilewar schon vor Jahren mehrfach als Antwort gegeben worden. Was fügt diese Antwort hinzu?
Dan Dascalescu
Auch warum od Sie Datei öffnen? Sollte die Antwort nicht das Schreiben von Dateien sein?
Michal