“Erreur: OK” lors de l’utilisation de fs.readFile () dans Node.js (après une itération d’environ cent mille)?

Je “marche” cent mille fichiers JSON, je lis le contenu et jette une erreur si quelque chose de mauvais se produit:

walk(__dirname + '/lastfm_test', 'json', function (err, files) { files.forEach(function (filePath) { fs.readFile(filePath, function (err, data) { if (err) throw err; }); }); }); 

La fonction de marche est largement inspirée par cette question (réponse de chjj). Après quelques itérations, la ligne if (err) throw err est exécutée. l’erreur est la suivante:

Erreur: OK, ouvrez ‘path / to / somejsonfile.json’

Une chance d’enquêter sur ce qui se passe ici? Je suis sûr que la fonction de fs.readFile() est correcte: en fait, remplacer l’appel fs.readFile() par console.log(filePath) affiche les chemins. sans fautes.

Quelques informations utiles: Windows 7 x64, node.exe x64 .0.10.5. Ensemble de données Last.fm téléchargé à partir d’ ici .

Je recommande d’utiliser le module graceful-fs à cette fin. Cela limitera automatiquement le nombre de descripteurs de fichiers ouverts. Il a été écrit par Isaac Schlueter, le créateur de npm et le mainteneur de Node. Il est donc plutôt solide. Le module de base nue vous permet de vous tirer une balle dans le pied.

Le “foreach-loop” exécute très souvent readFile . NodeJS commence à ouvrir les fichiers dans un fil d’arrière-plan. Mais aucun fichier n’est traité dans le thread principal NodeJS jusqu’à ce que la boucle foreach soit terminée (et que toutes les demandes d’ouverture de fichier soient planifiées). Pour cette raison, aucun fichier n’est traité (et plus tard fermé) lors de l’ouverture de tous les fichiers. À un moment donné, de nombreux fichiers sont ouverts et tous les descripteurs disponibles sont utilisés, ce qui génère un message d’erreur inutile.

Il y a de multiples soulutions à votre problème:

D’abord, vous pouvez ouvrir tous les fichiers de manière synchrone les uns après les autres. Mais cela ralentirait l’application et ne correspondrait pas au modèle de programmation basé sur les événements de NodeJS. (Mais c’est la solution la plus simple si la performance ne vous dérange pas)

Il serait préférable d’ouvrir seulement un nombre spécifique de fichiers à la fois (par exemple, environ 1 000 fichiers) et, après traitement, d’ouvrir le suivant.

Pseude Code:

 1. walk the file system and store all file name in an array 2. fs.readFile for a batch of files from the array 3. In the callback of readFile after processing, start opening more files from the array if not empty.