Zapisz obiekty do pliku za pomocą Node.js

83

Szukałem tego w całym stackoverflow / Google, ale nie mogę tego rozgryźć.

Skrobam linki do mediów społecznościowych podanej strony URL, a funkcja zwraca obiekt z listą adresów URL.

Kiedy próbuję zapisać te dane w innym pliku, wyprowadza do pliku zgodnie [object Object]z oczekiwaniami: [„ https://twitter.com/#!/101Cookbooks ”, „ http://www.facebook.com/ 101cookbooks ”], tak jak to ma miejsce, gdy console.log()otrzymuję wyniki.

To moja smutna próba odczytania i zapisania pliku w Node, próba odczytania każdej linii (adresu URL) i wprowadzenia danych przez wywołanie funkcji 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'); 
});   

dla odniesienia - gotHTMLfunkcja:

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
źródło
3
[object Object]jest przedmiotem toString. Jeśli chcesz przedstawić obiekt, użyj JSON.stringify.
elclanrs
2
Uważaj z JSON.stringify. Dzięki tablicom jesteś bezpieczny, ale gdy obiekty mają odwołania cykliczne, nie powiedzie się ( zobacz ten temat ). utilModuł obsługuje referencje okrężne.
Jim Schubert

Odpowiedzi:

71

obj jest tablicą w twoim przykładzie.

fs.writeFileSync (nazwa pliku danych [opcje]) wymaga albo Stringczy Bufferw parametrze danych. zobacz dokumentację .

Spróbuj zapisać tablicę w formacie łańcuchowym:

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

Lub:

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

edycja: Powodem, dla którego widzisz tablicę w swoim przykładzie, jest to, że implementacja węzła console.lognie tylko wywołuje toString, ale wywołuje util.format źródło console.js

Jim Schubert
źródło
5
Jeśli twój obiekt zawiera duże tablice, to nie zadziała, ponieważ metoda inspect wyświetli coś w rodzaju „45000 więcej ...]”
Coxer,
96

Opierając się na tym, co powiedział deb2fast, przekazałbym również kilka dodatkowych parametrów do JSON.stringify (), aby uzyskać ładny format:

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

Drugi parametr to opcjonalna funkcja zastępcza, której nie potrzebujesz w tym przypadku, więc nulldziała.

Trzeci parametr to liczba spacji używanych do wcięcia. 2 i 4 wydają się być popularnymi opcjami.

Chłopak
źródło
spowoduje to problem z zależnością cykliczną. Nie można przekonwertować zależności dwukierunkowych na format JSON.
Ozan Ertürk
W zapisanym pliku tekstowym brakuje znaku nowej linii na końcu pliku. Jakiś sposób to naprawić?
friederbluemle
1
@friederbluemle - Możesz + '\n'do tego wywołania stringify () dodać ten nowy wiersz.
Guy
1
Ten działał najlepiej dla mnie, ponieważ użycie zaakceptowanej odpowiedzi dało mi zły wynik.
Anshuman Kumar
20

Jeśli dostajesz, [object object]użyjJSON.stringify

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

U mnie to zadziałało.

deb2fast
źródło
10

Z mojego doświadczenia wynika, że ​​JSON.stringify jest nieco szybszy niż util.inspect. Musiałem zapisać wynik zapytania DB2 jako plik json, Zapytanie zwróciło obiekt 92k wierszy, konwersja zajęła bardzo dużo czasu z util.inspect, więc wykonałem następujący test, pisząc ten sam obiekt 1000 rekordów do pliku obiema metodami.

  1. JSON.Stringify

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

Czas: 3:57 (3 min 57 s)

Format wyniku:

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

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

Czas: 4:12 (4 min 12 s)

Format wyniku:

[ { PROB: '00001',
    BO: 'AXZ',
    CNTRY: '649' },
    ...
]
Netsmile
źródło
4

czy mógłbyś spróbować JSON.stringify (obj);

Lubię to

 var stringify = JSON.stringify(obj);
fs.writeFileSync('./data.json', stringify , 'utf-8'); 
Navvye Anand
źródło
1

Po prostu na wypadek, gdyby ktoś natknął się na to, używam biblioteki fs-extra w węźle i piszę obiekty javascript w pliku takim jak ten:

const fse = require('fs-extra');
fse.outputJsonSync('path/to/output/file.json', objectToWriteToFile); 
tljw86
źródło