Question

J'ai un fichier .csv fréquemment mis à jour (environ 20 à 30 fois par minute). Je souhaite insérer les nouvelles lignes ajoutées dans une base de données dès qu'elles sont écrites dans le fichier.

La classe FileSystemWatcher écoute le fichier. système de notifications de modification et peut déclencher un événement chaque fois qu'il y a une modification dans un fichier spécifié. Le problème est que FileSystemWatcher ne peut pas déterminer exactement quelles lignes ont été ajoutées ou supprimées (pour autant que je sache).

Une façon de lire ces lignes consiste à enregistrer et comparer le nombre de lignes entre les modifications et à lire la différence entre la dernière et la dernière dernière modification. Cependant, je recherche une solution plus propre (peut-être plus élégante).

Était-ce utile?

La solution

J'ai écrit quelque chose de très similaire. J'ai utilisé FileSystemWatcher pour obtenir des notifications sur les modifications. J'ai ensuite utilisé un FileStream pour lire les données (en gardant une trace de ma dernière position dans le fichier et en cherchant cela avant de lire les nouvelles données). J'ajoute ensuite les données lues à un tampon qui extrait automatiquement les lignes complètes, puis les envoie à l'interface utilisateur.

Remarque: "this.MoreData (..) est un événement dont l'auditeur ajoute au tampon susmentionné et gère l'extraction de la ligne complète.

Remarque: comme cela a déjà été mentionné, cela ne fonctionnera que si les modifications sont toujours des ajouts au fichier. Toute suppression entraînera des problèmes.

J'espère que cela vous aidera.

   public void File_Changed( object source, FileSystemEventArgs e )
    {
        lock ( this )
        {
            if ( !this.bPaused )
            {
                bool bMoreData = false;

                // Read from current seek position to end of file
                byte[] bytesRead = new byte[this.iMaxBytes];
                FileStream fs = new FileStream( this.strFilename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite );

                if ( 0 == this.iPreviousSeekPos )
                {
                    if ( this.bReadFromStart )
                    {
                        if ( null != this.BeginReadStart )
                        {
                            this.BeginReadStart( null, null );
                        }
                        this.bReadingFromStart = true;
                    }
                    else
                    {
                        if ( fs.Length > this.iMaxBytes )
                        {
                            this.iPreviousSeekPos = fs.Length - this.iMaxBytes;
                        }
                    }
                }

                this.iPreviousSeekPos = (int)fs.Seek( this.iPreviousSeekPos, SeekOrigin.Begin );
                int iNumBytes = fs.Read( bytesRead, 0, this.iMaxBytes );
                this.iPreviousSeekPos += iNumBytes;

                // If we haven't read all the data, then raise another event
                if ( this.iPreviousSeekPos < fs.Length )
                {
                    bMoreData = true;
                }

                fs.Close();

                string strData = this.encoding.GetString( bytesRead );
                this.MoreData( this, strData );

                if ( bMoreData )
                {
                    File_Changed( null, null );
                }
                else
                {
                    if ( this.bReadingFromStart )
                    {
                        this.bReadingFromStart = false;
                        if ( null != this.EndReadStart )
                        {
                            this.EndReadStart( null, null );
                        }
                    }
                }
            }
        }

Autres conseils

D'accord, FileSystemWatcher ne sait rien du contenu de votre fichier. Cela vous dira si cela a changé, etc., mais pas ce qui a changé.

Ajoutez-vous seulement au fichier? La poste ne savait pas trop si des lignes avaient été ajoutées ou si elles pouvaient également être supprimées. En supposant qu’elles soient ajoutées, la solution est assez simple, sinon vous ferez des comparaisons.

Je pense que vous devriez utiliser NTFS Change Journal ou similaire:

  

Le journal des modifications est utilisé par NTFS pour   fournir un journal persistant de tous   les modifications apportées aux fichiers sur le volume.   NTFS utilise la modification pour chaque volume   journal à suivre les informations sur   fichiers ajoutés, supprimés et modifiés .   Le journal des changements est beaucoup plus   efficace que les horodatages ou les fichiers   notifications pour déterminer les changements   dans un espace de noms donné.

Vous pouvez trouver une une description sur TechNet. . Vous devrez utiliser PInvoke dans .NET.

Je garderais le texte actuel en mémoire s'il était suffisamment petit, puis utiliserais un algorithme diff pour vérifier si le nouveau texte et le texte précédent avaient changé. Cette bibliothèque, http://www.mathertel.de/Diff/ , vous indiquera non seulement que quelque chose a changé mais ce qui a changé aussi. Vous pouvez ensuite insérer les données modifiées dans la base de données.

Hors de mon esprit, vous pouvez stocker la dernière taille de fichier connue. Vérifiez la taille du fichier et, s’il change, ouvrez un lecteur.

Recherchez ensuite le lecteur à la taille de votre dernier fichier et commencez à lire à partir de là.

Vous avez raison à propos de FileSystemWatcher. Vous pouvez écouter les événements créés, modifiés, supprimés, etc., mais vous n’allez pas plus loin que le fichier qui les a générés.

Avez-vous le contrôle du fichier lui-même? Vous pouvez légèrement modifier le modèle pour utiliser le fichier comme un tampon. Au lieu d'un fichier, en avoir deux. L'un est la mise en place, l'autre est la somme de toutes les sorties traitées. Lire toutes les lignes de votre & tampon; tampon " fichier, les traiter, puis les insérer à la fin d’un autre fichier représentant le total des lignes traitées. Ensuite, supprimez les lignes que vous avez traitées. De cette façon, toutes les informations de votre fichier sont en attente de traitement. Le problème est que si le système n’est pas autre chose qu’écrire (c’est-à-dire supprime également les lignes), cela ne fonctionnera pas.

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