Comme votre intuition l'a correctement deviné, la solution naïve avec une paire de exists / writeFile
Les appels sont erronés. Le code asynchrone fonctionne de manière imprévisible. Et dans ce cas précis, c'est
- Y a-t-il un fichier
a.txt
? - Non.
- (Dossier
a.txt
est créé par un autre programme)
- Écrire à
a.txt
si c'est possible. - D'accord.
Mais oui, nous pouvons le faire en un seul appel. Nous travaillons avec un système de fichiers, donc c'est une bonne idée de lire le manuel du développeur sur fs
. Et hé, voici une partie intéressante.
w' - Ouvre le fichier pour l'écriture. Le fichier est créé (s'il n'existe pas) existe pas) ou tronqué (s'il existe).
wx' - Comme 'w' mais échoue si le chemin existe.
Donc tout ce que nous avons à faire est d'ajouter wx
a la fs.open
appel. Mais hé, nous n'aimons pas fopen
-comme IO. Lisez la suite fs.writeFile
un peu plus.
fs.readFile(nom du fichier[, options], callback)#.
filename Chaîne
Options Objet
encodage Chaîne | Null par défaut = null
flag String default = 'r
Fonction callback
Ce options.flag
semble prometteur. Nous essayons donc
fs.writeFile(path, data, { flag: 'wx' }, function (err) {
if (err) throw err;
console.log("It's saved!");
});
Et cela fonctionne parfaitement pour une seule écriture. Je pense que ce code échouera de manière encore plus bizarre si vous essayez de résoudre votre tâche avec lui. Vous avez un atomaire "check for a_#.jpg
existence, et y écrire s'il est vide", mais toutes les autres opérations de l'opération fs
n'est pas verrouillé, et a_1.jpg
peut disparaître spontanément alors que vous êtes déjà en train de vérifier. a_5.jpg
. La plupart * Les systèmes de fichiers ne sont pas ACID et le fait que vous soyez capable d'effectuer au moins quelques opérations atomiques est miraculeux. Il est très probable que wx
Le code ne fonctionnera pas sur certaines plateformes. Donc pour le bien de votre santé mentale, utiliser la base de données, enfin .
Quelques informations supplémentaires pour ceux qui souffrent
Imaginez que nous écrivions quelque chose comme memoize-fs
qui met en cache les résultats des appels de fonctions dans le système de fichiers pour nous faire gagner du temps réseau/cpu. Pourrions-nous ouvrir le fichier en lecture s'il existe, et en écriture s'il n'existe pas, tout cela en un seul appel ? Jetons un regard amusé sur ces drapeaux. Après un certain nombre d'exercices mentaux, nous pouvons voir que a+
fait ce que nous voulons : si le fichier n'existe pas, il en crée un et l'ouvre à la fois pour la lecture et l'écriture, et si le fichier existe, il le fait sans effacer le fichier (comme le fait w+
serait). Mais maintenant, nous ne pouvons l'utiliser ni dans (smth)File
ni dans create(Smth)Stream
fonctions. Et cela semble être une fonction manquante.
N'hésitez donc pas à déposer une demande de fonctionnalité (ou même un bogue) sur Node.js github, car l'absence d'API de système de fichiers asynchrones atomiques est un inconvénient de Node. Bien que n'attendez pas ne changera pas de sitôt.
Éditer. Je souhaite créer un lien vers les articles de Linus et par Dan Luu sur pourquoi exactement vous ne voulez pas faire quelque chose d'intelligent avec votre fs
des appels, parce que la revendication a été laissée en grande partie non fondée sur quoi que ce soit.