2012-10-29 11 views
6

Próbuję dokonać odczytu parametrów pliku. Kiedy robię ten kod:Problemy z używaniem fs.stat w nodejs

var fs = require('fs'), 
    size = new Object(); 
fs.stat(file, function(err,stats){ 
     if(!err){ 
      size=stats; 
     } 
     }) 
    console.log(size); 

It`s ok, kiedy próbuje użyj funkcji:

var fs = require('fs'), 
    size = new Object(); 
function writeinfile(file){ 
    fs.stat(file, function(err,stats){ 
     if(!err){ 
      size=stats; 
     } 
     }) 
    console.log(size.size); 
} 
writeinfile('error.log'); 

It`s nie działać. Czy możesz mi pomóc, że wariant 2 działa?

Odpowiedz

0

Istnieje kilka obserwacji do kodu. Ale jesteśmy tutaj, aby dowiedzieć się:

  1. Upewnij umieścić console.log wewnątrz zwrotnego (czyli tuż poniżej size=stats), w ten sposób można uzyskać potrzebne informacje, po tym jak funkcja ma swoje zadanie.

  2. Dodaj powyższej linii if (!err):

    jeśli (ERR) console.log (eee)

Zobaczysz następujące

{ [Error: ENOENT, stat 'error.log'] errno: 34, code: 'ENOENT', path: 'error.log' } 

Oznacza to błąd na ścieżce. Łatwa naprawa: użyj fs.exists(), aby sprawdzić, czy plik istnieje i/lub, zawsze pamiętaj, aby poprzedzić nazwę pliku przez __dirname.

  1. Ostatni wiersz mówi o writeinfile, ale fs.stats daje informację o pliku ... I sugerują, że lepiej byłoby fs.write() funkcja dla tego zadania.
+0

Chcę zapisać informacje w pliku, zmienić nazwę pliku, gdy osiągnie żądany rozmiar (za pomocą fs.rename) i zapisać informacje w nowym pliku za pomocą fs.write. Planuję uzyskać rozmiar pliku w zmiennej "rozmiar" użyj fs.stat i użyj jeśli (rozmiar <= 238084) (fs.rename (...)) else fs.write (....). – IIEIIEJI

12

Twój plik console.log znajduje się poza twoim numerem fs.stat. Naprawiono go:

var fs = require('fs'), 
    size = new Object(); 
function writeinfile(file){ 
    fs.stat(file, function(err,stats){ 
     if(!err){ 
      size=stats; 
      console.log(size.size); 
     } 
     }) 

} 
writeinfile('error.log'); 

Ja również przepisany kod używać więcej idiomatyczne (więcej wspólnego) składni w node.js:

var fs = require('fs'); 

function writeinfile (file, cb) { 
    fs.stat(file, function(err,stats){ 
    if(err) return cb(err); 
    cb(null, stats.size); 
    }) 
} 

writeinfile('error.log', function(err, size) { 
    if(err) { 
    console.log(err); 
    return; 
    } 
    console.log('The size of the file is ' + size); 
}); 

Jak Herman wspomniano w swojej odpowiedzi, że to będzie dobry pomysł, aby wybrać lepszą nazwę funkcji, jeśli nie piszesz do pliku.

Ostatnia rzecz, w języku Javascript, można użyć {} jako skrótu do new Object(). Na przykład: var size = {};

1

W twoim przykładzie nie należy oczekiwać, że wartość rozmiaru zostanie ustawiona, gdy uruchomi się konsola.log (rozmiar) ze względu na asynchroniczną naturę fs.stat().

Oto co faktycznie występuje, w kolejności:

  1. wymagają modułu fs i wystąpienie nowego size obiekt.
  2. zadzwonić fs.stat (ścieżka, cb) z zwrotnego
  3. zadzwonić console.log (rozmiaru)
  4. wtedy, w pewnym momencie w przyszłości, fs.stat() wywołuje twój oddzwonienie

Rzeczy dzieją się w tej kolejności, ponieważ nie można przewidzieć czasu potrzebnego na wykonanie wymaganego wywołania systemowego pliku z powodu asynchronicznej natury pliku io. W zależności od tego, co obecnie robi płyta, może to zająć od 4 do 4000 ms lub więcej.

Dlatego polegamy na wywoływaniach zwrotnych, ponieważ są one zagwarantowane, gdy funkcja, do której zostały zastosowane, jest kompletna, lub w tym przypadku, gdy określono status ścieżki do pliku.

Proszę, nie czuj się źle. Jest to jeden błąd, który powoduje, że przy programowaniu asynchronicznym i najtrudniejszym pomysłem jest owinięcie głowy podczas programowania węzła.

+0

+1 Na początku callbacks były bardzo frustrujące! –

1

Musisz umieścić console.log (size.size); wewnątrz funkcji wywołania zwrotnego, ale myślę, że muszę wyjaśnić lepiej.

Musisz dowiedzieć się o połączeniach asynchronicznych i pętli zdarzeń Node.js. Node.js został stworzony, aby łączyć zasoby w lepszy sposób niż tworzenie wątków dla problemów, które są bardziej Intensywne IO (np. Serwery WWW) niż CPU Intensive. Pomysł polega na tym, że pojedynczy wątek dla logiki z nieblokującymi wywołaniami do korzystania z IO jest lepszy niż tworzenie wielu wątków i funkcji bloków wywołań do korzystania z IO.

Jeśli zaprogramować w innym języku, należy zapoznać się z sinchronous wersji swojego algorytmu:

var fs = require('fs'), 
size = new Object(); 
function writeinfile(file) { 
    var stats = fs.statSync(path); 
    size = stats.size; 
    console.log(size); 
}; 

writeinfile('error.log'); 

Jest to kod node.js, ale to nie jest sposób Node. Kiedy wywołasz statSync(), twój blok skryptu czeka na odczyt statystyk z dysku.

ALE, jeśli używasz tylko fs.stat(), twój program będzie działał do końca kodu, GDY dysk odczytuje. Wszystkie następne linie zostaną uruchomione, zanim program osiągnie pętlę zdarzeń. Dopiero gdy statystyki będą gotowe, a program będzie działał do końca, pętla zdarzeń wywoła funkcję zwrotną, którą przekazujesz przez wywołanie fs.stat(callback).

W swoim kodzie wywołujesz stat (wersja asynchroniczna) i próbujesz użyć wartości, która nie jest jeszcze gotowa, ponieważ kod po wywołaniach asynchronicznych zawsze będzie uruchamiany przed wywołaniem wywołania zwrotnego.

Pierwsza wersja, którą myślę, działa właśnie dlatego, że powinieneś wpisywać kod ręcznie w tłumaczu, więc czas potrzebny do wpisania następnej linii jest wystarczający do osiągnięcia przez program pętli zdarzeń. W tym trybie, za każdym razem, gdy wpisujesz polecenie, naciśnij enter i ten kod zostanie uruchomiony, to znaczy otrzymasz zwrot, zdarzenia w pętli zdarzeń będą wywoływane po.

Powiązane problemy