Question

J'ai un programme qui a besoin de charger des fichiers d'un répertoire dès qu'ils sont écrits. Je suis le FileSystemWatcher me notifier les changements dans le répertoire. Plutôt que de vérifier l'événement pour ce que j'ai changé les fichiers écrit tout simplement et commencer à traiter tout ce que je trouve.

Pour éviter d'essayer de lire un fichier qui est encore en cours d'écriture je code comme:

try {
    fs = fi.Open(FileMode.Open, FileAccess.ReadWrite,
                    FileShare.None);
    message = new byte[fs.Length];
    int br = fs.Read(message, 0, (int)fi.Length);
}
catch (Exception e) {
    // I'll get it next time around
    return;
}
finally {
    if (fs != null)
        fs.Close();
}

Le problème est que pour certains fichiers, environ 1 dans 200, le programme lu tous les zéros. Longueur de fichier est correct, mais le contenu semble être tous zéro octets. Quand je vérifie le dernier fichier je trouve qu'il ne contient des données correctes réelles. Je pensais que la façon dont j'ouvrir le fichier empêcherait l'accès prématuré au fichier.

Je teste en copiant les fichiers dans le répertoire avec la commande DOS « copie InFile_0 * dropdir » (environ 100 fichiers par exécution.) Peut-être cette commande ne la copie en deux étapes: 1) allouer de l'espace et 2) fill l'espace et mon programme saute de temps en temps au milieu des deux.

Toutes les idées sur la façon de coder ce sont fiables?

Mise à jour: Je n'ai pas de contrôle sur le programme d'écriture - il pourrait être quelque chose. On dirait que je dois le code défensivement.

Était-ce utile?

La solution

Vous frappez une condition de course. Ça ne va empirer d'ici (avec les systèmes de fichiers en réseau, etc.) à moins que vous fixer définitivement.

Essayez d'avoir le programme écrire les fichiers écrivent chacun en utilisant un « whatever.tmp » nom, puis fermez, puis le renommer. Lors de la lecture, ignorer les fichiers .tmp.

Ou, gardez un fichier zéro nommé « sentinelle » ou quelque chose comme dans le répertoire. Obtenez le programme écrit les fichiers de réécrire le fichier sentinelle après chaque écriture réussie d'un autre fichier. Alors, ne tentez pas de lire les fichiers dont la date de modification / horaire> = la date / heure de modification du fichier sentinelle.

Ou, si vous avez aucun contrôle sur l'auteur des fichiers, vérifiez chaque modification du fichier, date / heure contre la date / heure du système actuel. Laissez les fichiers en âge une quantité appropriée (quelques secondes si elles sont petites, plus si elles sont plus grandes) avant d'essayer de les lire.

Bonne chance. Ceci est une douleur notoire dans le cou.

Autres conseils

Eh bien, je suis en désaccord avec le post précédent par @Ollie Jones.

Vous avez déjà établi un accès exclusif au fichier, donc pas de problème de condition de course.

Je pense que vous devriez examiner plus attentivement le comportement de l'écrivain. Et essayer de réduire les interférences sur l'accès aux fichiers en lecture seule, partager tous les accès:

fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

Cela pourrait échouer votre lecture mais réduire les erreurs d'écriture. Pour décider du moment de lire en toute sécurité, vous pouvez vérifier le temps de fichier ou la taille du fichier ou autre. Si plusieurs fichiers sont écrits par la suite, vous pouvez commencer à lire le premier fichier après la deuxième fichier créé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top