Soyez le premier à donner votre avis sur cette source.
Vue 16 165 fois - Téléchargée 951 fois
using System; using System.ComponentModel; using System.IO; using System.Text; using System.Windows.Forms; namespace Editor { public partial class Form1 : Form { /// <summary> /// Nom du fichier chargé /// </summary> private string filename; /// <summary> /// Taille actuellement chargée du fichier /// </summary> private int filesize = 0; /// <summary> /// Constructeur /// </summary> public Form1() { InitializeComponent(); } #region Events /// <summary> /// Evénements déclenché lorsque le fichier surveillé est modifié /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e) { try { // Chargement du fichier surveillé LoadFile(filename); } catch (Exception ex) { string errorMessage = ex.Message; while (ex.InnerException != null) { ex = ex.InnerException; errorMessage += "\n" + ex.Message; } MessageBox.Show(errorMessage, "Unexpected error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// Sélection d'un fichier à surveiller et chargement de celui-ci /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonLoad_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) { try { // Initialisation à zéro de la taille du fichier déjà chargé filesize = 0; // Sauvgarde du nom du fichier à charger filename = openFileDialog1.FileName; // Affichage du nom du fichier dans la barre de titre de la fenetre this.Text = "FileWatcher - " + filename; // Chargement du fichier sélectionné LoadFile(filename); } catch (Exception ex) { string errorMessage = ex.Message; while (ex.InnerException != null) { ex = ex.InnerException; errorMessage += "\n" + ex.Message; } MessageBox.Show(errorMessage, "Unexpected error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } /// <summary> /// Permet d'arrêter ou reprendre le suivi du fichier chargé /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonStop_Click(object sender, EventArgs e) { if (buttonStop.Text == "Stop") { fileSystemWatcher1.EnableRaisingEvents = false; buttonStop.Text = "Start"; } else { fileSystemWatcher1.EnableRaisingEvents = true; buttonStop.Text = "Stop"; } } #endregion private void LoadFile(string filename) { // Si il y a déjà une tâche de fonds l'arrêter if (backgroundWorker.IsBusy) backgroundWorker.CancelAsync(); // Attendre pour etre certain qu'il n'y plus de tâche de fonds en cours while (backgroundWorker.IsBusy) ; // Activer la barre de chargement toolStripProgressBar.Visible = true; // Lancer le chargement en arrière plan backgroundWorker.RunWorkerAsync(filename); } #region delegate private delegate void setProgressBarPecentage(int percentage); /// <summary> /// Procédure pour afficher l'état d'avancement du chargement du fichier /// </summary> /// <param name="percentage"></param> private void SetProgressBarPecentage(int percentage) { toolStripProgressBar.Value = percentage; } #endregion #region worker /// <summary> /// Routine qui est exécutée en tâche de fonds /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { try { // Récupération du handle sur le process en cours BackgroundWorker worker = sender as BackgroundWorker; // ouverture du fichier en mode partagé FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); // Positionnement à l'endroit jusqu'où on avait déjà lu le fichier fs.Seek(filesize, SeekOrigin.Begin); // Total de byte déjà lu dans le fichier int totalRead = filesize; // Nouvelle taille du fichier filesize = (int)fs.Length; // Initialisation du buffer de lecture byte[] buffer = new byte[1024]; // Nbre de caractère lu à chaque incrément int count = 0; // Chaîne de réception pour la lecture du fichier string texte = ""; while ((count = fs.Read(buffer, 0, 1024)) != 0 && !worker.CancellationPending) { totalRead += count; // Transformation du tableau byte[] en string texte += Encoding.ASCII.GetString(buffer, 0, count); // Modification de l'état d'avancement worker.ReportProgress((totalRead * 100) / filesize); } // Initialisation de la chaîne de retour avec le contenu du fichier e.Result = texte; // Fermeture du Flux fs.Close(); if (worker.CancellationPending) { e.Cancel = true; } } catch (Exception ex) { string errorMessage = ex.Message; while (ex.InnerException != null) { ex = ex.InnerException; errorMessage += "\n" + ex.Message; } MessageBox.Show(errorMessage, "Unexpected error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// Mise à jour de la barre de progression /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { // Vérification si on est dans un thread et éventuellement appel du délégate pour pouvoir faire mise à jour if (this.InvokeRequired) this.Invoke(new setProgressBarPecentage(SetProgressBarPecentage), new object[] { e.ProgressPercentage }); else SetProgressBarPecentage(e.ProgressPercentage); } /// <summary> /// Méthode appelée lorsque le fichier a été chargé /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // Vérification si tout s'est bien déroulé if (e.Cancelled) { // L'utilisateur à annulé l'opération toolStripStatusLabel1.Text = string.Format("Aborted by user."); } else if (e.Error != null) { // Il y a eu une erreur pendant le traitement. string msg = String.Format("An error occurred: {0}", e.Error.Message); MessageBox.Show(msg); } else { // Tout s'est bien déroulé // Affichage du fichier dans le contrôle ICsharpCode.TextEditor textEditorControl1.Text += e.Result.ToString(); // Calcul du nombre de ligne dans le contrôle ICsharpCode.TextEditor int totalLine = textEditorControl1.Document.GetLineNumberForOffset(textEditorControl1.Text.Length); // Déplacement jusqu'à la dernière ligne textEditorControl1.ActiveTextAreaControl.ScrollTo(totalLine, 1); // Affichage d'inforamtions dans la barre du d'info du bas de l'écran toolStripStatusLabel1.Text = string.Format("{0} lines - last accesss : {1} - {2} ", totalLine, File.GetLastWriteTime(filename).ToShortDateString(), File.GetLastWriteTime(filename).ToLongTimeString()); // Initialisation de la surveillance du fichier chargé fileSystemWatcher1.Filter = Path.GetFileName(filename); fileSystemWatcher1.Path = Path.GetDirectoryName(filename); fileSystemWatcher1.EnableRaisingEvents = true; // Activation du boutton d'arrêt de surveillance buttonStop.Enabled = true; } // Cacher la barre de progression du chargement de fichier toolStripProgressBar.Visible = false; } #endregion } }
Si tu regardes bien la source, tu verras que je ne recharge que la fin du fichier s'il y a une modification de celui-ci. C'est la raison pour laquelle j'utilise la variable filesize qui me permet de sauver le nombre d'octets que j'ai déjà lu et de faire ensuite un seek.
Pour le textStream, cela pose un problème si le fichier est déjà ouvert par un processus quelconque. J'étais parti sur ce principe, mais si tu veux monitorer un fichier log d'apache, par exemple, et bien tu ne sais tout simplement pas ouvrir le fichier et c# te prévient gentiment que le fichier est déjà ouvert par quelqu'un d'autre.
Dans ton exemple tu montres un fichier de trace www. Je te conseille de prévoir le cas (à la discrétion de l'utilisateur) d'une modification par ajout en ne rechargeant que la fin du fichier à chaque modif. Tu gagnerait ainsi un temps précieux.
Sinon, pour lire une fichier texte, tu peux utiliser un textStream et la fonction ReadToEnd pour le lire en une fois.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.