c # - la lecture du fichier journal binaire qui est mis à jour toutes les 6 secondes avec 12k de données

StackOverflow https://stackoverflow.com/questions/1170538

  •  19-09-2019
  •  | 
  •  

Question

J'ai un fichier journal binaire avec des données de transmission en continu d'un capteur (Int16).
Toutes les 6 secondes, 6000 échantillons de type Int16 sont ajoutées, jusqu'à ce que le capteur est déconnecté.

Je dois interroger ce fichier à intervalles réguliers, en continuant de la dernière position de lecture. Est-il préférable de a) garder un filestream et lecteur binaire ouvert et instancié entre les lectures b) instancier filestream et lecteur binaire chaque fois que je besoin de lire (et de garder une variable externe pour suivre la dernière position de lecture) c) quelque chose de mieux?

EDIT: Quelques bonnes suggestions à ce jour, ont besoin d'ajouter que l'application « serveur » est fourni par un fournisseur de source extérieure et ne peut pas être modifié

.
Était-ce utile?

La solution

Si elle est toujours d'ajouter la même quantité de données, il peut être judicieux de le rouvrir. Vous pouvez trouver la longueur avant de l'ouvrir, puis arrondir au nombre entier de « ensembles d'échantillons » disponibles, juste au cas où vous l'attraper alors qu'il est encore à écrire les données. Cela peut signifier que vous lisez moins que vous peut lire (si l'écriture se termine entre vous vérifier la durée et à partir de la lecture), mais vous allez prendre la prochaine fois.

Vous devez vous assurer que vous utilisez les options de partage appropriées pour que l'écrivain peut encore écrire pendant que vous lisez bien. (L'auteur devra probablement avoir été écrit avec cela aussi à l'esprit.)

Autres conseils

Peut-on utiliser MemoryMappedFiles ?

Si vous le pouvez, le mappage du fichier dans la mémoire et le partager entre les processus, vous serez en mesure de lire les données en incrémentant simplement le décalage pour le pointeur à chaque fois.

Si vous le combinez avec un événement, vous pouvez signaler votre lecteur quand il peut aller dans une lecture des informations. Il n'y aura pas besoin de bloquer quoi que ce soit que le lecteur sera toujours lire les données « anciennes » qui a déjà été écrit.

Je recommande d'utiliser des tuyaux, ils agissent comme des fichiers, à l'exception des données de flux directement entre les applications, même si les applications fonctionnent sur différents PC (bien que ce soit vraiment une option que si vous êtes en mesure de changer les deux applications). Check it out sous l'espace de noms "de System.IO.Pipes".

P.S. Vous utilisez un « nom » pipe pour cela (tuyaux sont pris en charge dans « c » et, donc en gros tout langage de programmation de moitié décent devrait être en mesure de les mettre en œuvre)

Je pense que (a) est le meilleur parce que:

  • Position actuelle sera incrémenté que vous lisez et vous n'avez pas besoin de vous soucier de le stocker quelque part;
  • Vous n'avez pas besoin de l'ouvrir et de rechercher la position requise (il ne devrait pas être beaucoup plus lents à rouvrir, mais le garder ouvert donne OS quelques conseils pour l'optimisation, je crois) chaque fois que vous sondage y;
  • D'autres solutions que je peux penser à PInvokes nécessite de primitives de synchronisation interprocessus du système. Et ils ne seront pas déjà plus rapide que les opérations de fichiers dans le cadre.

Il vous suffit de définir des indicateurs appropriés de partage de fichiers:

Juste par exemple:

Serveur:

using(var writer = new BinaryWriter(new FileStream(@"D:\testlog.log", FileMode.Append, FileAccess.Write, FileShare.Read)))
{
    int n;
    while(Int32.TryParse(Console.ReadLine(), out n))
    {
        writer.Write(n);
        writer.Flush(); // write cached bytes to file
    }
}

Client:

using (var reader = new BinaryReader(new FileStream(@"D:\testlog.log", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
    string s;
    while (Console.ReadLine() != "exit")
    {
        // allocate buffer for new ints
        Int32[] buffer = new Int32[(reader.BaseStream.Length - reader.BaseStream.Position) / sizeof(Int32)];

        Console.WriteLine("Stream length: {0}", reader.BaseStream.Length);
        Console.Write("Ints read: ");
        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = reader.ReadInt32();
            Console.Write((i == 0 ? "" : ", ") + buffer[i].ToString());
        }
        Console.WriteLine();
    }
}

vous pouvez également diffuser les données dans une base de données, plutôt que d'un fichier comme une autre alternative, alors vous ne seriez pas à vous soucier de verrouillage de fichiers.

mais si vous êtes coincé avec la méthode de fichier, vous pouvez fermer le fichier chaque fois que vous lire les données; cela dépend beaucoup de la façon dont le processus d'écriture dans le fichier va être, et si elle peut détecter une opération de verrouillage des fichiers et répondre de façon appropriée sans s'écraser horriblement compliquée.

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