Schreiben Sie Objekte mit Node.js in eine Datei

80

Ich habe überall in Stackoverflow / Google danach gesucht, kann es aber nicht herausfinden.

Ich kratzte Social-Media-Links einer bestimmten URL-Seite und die Funktion gibt ein Objekt mit einer Liste von URLs zurück.

Wenn ich versuche, diese Daten in eine andere Datei zu schreiben, werden sie wie [object Object]erwartet in die Datei ausgegeben: [' https://twitter.com/#!/101Cookbooks ', ' http://www.facebook.com/ 101cookbooks '] wie es tut, wenn ich console.log()die Ergebnisse.

Dies ist mein trauriger Versuch, eine Datei in Node zu lesen und zu schreiben, indem ich versuche, jede Zeile (die URL) zu lesen und über einen Funktionsaufruf einzugeben request(line, gotHTML):

fs.readFileSync('./urls.txt').toString().split('\n').forEach(function (line){
    console.log(line); 
    var obj = request(line, gotHTML); 
    console.log(obj); 
    fs.writeFileSync('./data.json', obj , 'utf-8'); 
});   

als Referenz - die gotHTMLFunktion:

function gotHTML(err, resp, html){ 
    var social_ids = []; 

    if(err){
        return console.log(err); 
    } else if (resp.statusCode === 200){ 
        var parsedHTML = $.load(html); 

        parsedHTML('a').map(function(i, link){
            var href = $(link).attr('href');
            for(var i=0; i<socialurls.length; i++){
                if(socialurls[i].test(href) && social_ids.indexOf(href) < 0 ) {
                    social_ids.push(href); 
                }; 
            }; 
        })
    };

    return social_ids;
};
sarahbkim
quelle
2
[object Object]ist ein Objekt toString. Wenn Sie die Darstellung des Objekts wünschen, verwenden Sie JSON.stringify.
elclanrs
2
Sei vorsichtig mit JSON.stringify. Mit Arrays sind Sie sicher, aber wenn Objekte Zirkelverweise haben, schlägt dies fehl ( siehe dieses Thema ). Das utilModul verarbeitet Zirkelverweise.
Jim Schubert

Antworten:

68

obj ist ein Array in Ihrem Beispiel.

fs.writeFileSync (Dateiname, Daten, [Optionen]) erfordert entweder Stringoder Bufferim Datenparameter. siehe docs .

Versuchen Sie, das Array in einem Zeichenfolgenformat zu schreiben:

// writes 'https://twitter.com/#!/101Cookbooks', 'http://www.facebook.com/101cookbooks'
fs.writeFileSync('./data.json', obj.join(',') , 'utf-8'); 

Oder:

// writes ['https://twitter.com/#!/101Cookbooks', 'http://www.facebook.com/101cookbooks']
var util = require('util');
fs.writeFileSync('./data.json', util.inspect(obj) , 'utf-8');

edit: Der Grund, warum Sie das Array in Ihrem Beispiel sehen, ist, dass die Implementierung von node console.lognicht nur toStringaufruft, sondern util.format see console.js source aufruft

Jim Schubert
quelle
5
Wenn Ihr Objekt große Arrays enthält, funktioniert dies nicht, da die Inspect-Methode so etwas wie "45000 more ...]"
ausgibt
93

Aufbauend auf dem, was deb2fast sagte, würde ich auch ein paar zusätzliche Parameter an JSON.stringify () übergeben, um es in ein hübsches Format zu bringen:

fs.writeFileSync('./data.json', JSON.stringify(obj, null, 2) , 'utf-8');

Der zweite Parameter ist eine optionale Ersetzungsfunktion, die Sie in diesem Fall nicht benötigen null.

Der dritte Parameter ist die Anzahl der Leerzeichen, die zum Einrücken verwendet werden sollen. 2 und 4 scheinen beliebte Entscheidungen zu sein.

Kerl
quelle
es wird ein zirkuläres Abhängigkeitsproblem verursachen. Zwei-Wege-Abhängigkeiten konnten nicht in JSON konvertiert werden.
Ozan Ertürk
In der geschriebenen Textdatei fehlt das Zeilenumbruchzeichen am Ende der Datei. Wie kann man das beheben?
Friederbluemle
1
@friederbluemle - Sie können + '\n'zu diesem Aufruf von stringify () diese neue Zeile hinzufügen.
Guy
20

Wenn Sie bekommen, [object object]dann verwenden SieJSON.stringify

fs.writeFile('./data.json', JSON.stringify(obj) , 'utf-8');

Es hat bei mir funktioniert.

deb2fast
quelle
10

Nach meiner Erfahrung ist JSON.stringify etwas schneller als util.inspect. Ich musste das Ergebnisobjekt einer DB2-Abfrage als JSON-Datei speichern. Die Abfrage gab ein Objekt mit 92.000 Zeilen zurück. Die Konvertierung mit util.inspect dauerte sehr lange. Daher führte ich den folgenden Test durch, indem ich dasselbe 1000-Datensatzobjekt schrieb zu einer Datei mit beiden Methoden.

  1. JSON.Stringify

    fs.writeFile('./data.json', JSON.stringify(obj, null, 2));
    

Zeit: 3:57 (3 Min. 57 Sek.)

Ergebnisformat:

[
  {
    "PROB": "00001",
    "BO": "AXZ",
    "CNTRY": "649"
   },
  ...
]
  1. util.inspect

    var util = require('util');
    fs.writeFile('./data.json', util.inspect(obj, false, 2, false));
    

Zeit: 4:12 (4 min 12 sec)

Ergebnisformat:

[ { PROB: '00001',
    BO: 'AXZ',
    CNTRY: '649' },
    ...
]
Netsmile
quelle
4

Könnten Sie versuchen, JSON.stringify (obj) auszuführen?

So was

 var stringify = JSON.stringify(obj);
fs.writeFileSync('./data.json', stringify , 'utf-8'); 
Navvye Anand
quelle
0

Nur für den Fall, dass jemand anderes darüber stolpert, verwende ich die fs-extra-Bibliothek im Knoten und schreibe Javascript-Objekte in eine Datei wie diese:

const fse = require('fs-extra');
fse.outputJsonSync('path/to/output/file.json', objectToWriteToFile); 
tljw86
quelle