2010-06-04 6 views
5

J'ai une application que j'ai été chargé de nettoyer après. L'application elle-même est relativement simple: elle exécute une requête SQL, consomme un service Web et envoie les résultats dans un fichier journal. Mon travail consiste à archiver les fichiers sur notre NAS une fois l'application terminée. Il verrouille les fichiers exclusivement jusqu'à ce qu'ils soient terminés, ce qui ajoute un peu de complexité. Je ne suis pas autorisé à toucher l'application, seulement les journaux. Quoi qu'il en soit mon application est assez simple:Reverse Streamreader

  1. Vérifiez si le fichier peut être ouvert (catch IOException) et marquez-le comme accessible dans un bool [] si aucune exception n'est levée.
  2. En parcourant le tableau de fichiers marqué vrai, lire chaque ligne du fichier dans un StreamReader en utilisant la méthode ReadLine. Étant donné que l'application rencontre parfois un problème de hic et ne se termine pas, je ne peux pas simplement utiliser l'exception IOException pour indiquer si le fichier est terminé. Je dois analyser le texte.
  3. Si le texte indiquant l'achèvement est trouvé, compressez le fichier, chargez le fichier archivé sur le NAS et supprimez l'original.

Mon code fonctionne, il prend juste beaucoup de temps (les fichiers journaux sont chacun d'environ 500 Mo). Mes réflexions sur l'amélioration impliquent de commencer ma recherche depuis le bas du fichier plutôt que depuis le haut, mais le StreamReader ne supporte pas une telle méthode. Je ne peux pas utiliser la méthode ReadToEnd, puis inverser la lecture car cela génère une exception de mémoire insuffisante. Des idées sur la façon dont je pourrais accélérer l'analyse du fichier journal?

+0

suivant ne savez-vous que l'analyse des fichiers est la partie lente? pas ziping, copier sur NAS, supprimer ou essayer d'ouvrir le fichier (et éventuellement échouer) toutes ces choses sonnent comme ils pourraient prendre un certain temps – luke

+0

Dupe possible: http://stackoverflow.com/questions/452902/how-to-read -a-text-file-inverse-avec-iterator-in-c –

+1

Bonne question. Ouais, c'est certainement l'analyse qui est la partie la plus longue de l'exécution. J'ai séparé le code en fonctions individuelles et mis des points de rupture sur chacun. Le zipping prend environ 30 à 45 secondes, l'analyse peut durer plus de deux heures. – monkeyninja

Répondre

6

Je suppose que vous recherchez un seul marqueur à la fin du fichier pour déterminer s'il est terminé? Si oui, je suppose également que le marqueur est d'une longueur connue, par exemple un seul octet ou une séquence de 3 octets, etc.

Si les hypothèses ci-dessus sont correctes, vous pouvez ouvrir FileStream, Seek jusqu'à la fin du fichier moins la longueur du marqueur attendu lire les octets et si le marqueur est présent et complet, vous savez que vous pouvez traiter le fichier.

Cherchant à la fin -3 octets peut être fait avec le code comme le

// Seek -3 bytes starting from the end of the file 
fileStream.Seek(-3, SeekOrigin.End); 
+0

La recherche peut être une opération plus coûteuse que la lecture séquentielle et faire plusieurs recherches peut être assez lent. – josephj1989

+0

C'est quelque chose que je n'ai pas encore essayé, donc ça vaut le coup. Je vais essayer de mettre en œuvre la recherche et voir si cela accélère les choses ou non. Merci a tous. – monkeyninja

+3

@ josephj1989, dites-vous qu'il est plus rapide de lire un fichier de 500 Mo ligne par ligne ou en morceaux amicaux jusqu'à la fin que de simplement chercher directement à la fin? Et pourquoi plusieurs cherche, mon hypothèse affirmée est que le marqueur est à la fin du fichier donc seulement une seule recherche. –