C # - al leer el archivo de registro binario que se actualiza cada 6 segundos con 12k de datos

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

  •  19-09-2019
  •  | 
  •  

Pregunta

Tengo un archivo de registro binario con el flujo de datos desde un sensor (Int16).
se añaden Cada 6 segundos, 6000 muestras de tipo Int16, hasta que se desconecta el sensor.

Necesito consultar este archivo en intervalos regulares, continuando desde la última posición de lectura. ¿Es mejor a) mantener un filestream y lector binaria abierto y instanciado entre lecturas b) crear una instancia filestream y el lector binaria cada vez que tengo que leer (y mantener una variable externa para realizar un seguimiento de la última posición de lectura) c) algo mejor?

EDIT: Algunas sugerencias hasta ahora, tienen que añadir que la aplicación "servidor" es suministrado por un proveedor de fuente externa y no puede ser modificado

.
¿Fue útil?

Solución

Si siempre ha de añadir la misma cantidad de datos, puede tener sentido para volver a abrirla. Es posible que desee para averiguar la longitud antes de abrirlo y, a continuación, redondeando hacia abajo a toda la serie de "grupos de muestras" disponibles, en caso de que se captura mientras aún está escribiendo los datos. Eso puede significar que lee menos de lo que podría leer (si la escritura termina entre usted comprobación de la longitud y de iniciar la lectura), pero se podrán ponerse al día la próxima vez.

Usted tendrá que asegurarse de que utiliza las opciones para compartir adecuadas para que el escritor todavía puede escribir mientras estás leyendo sin embargo. (El escritor probablemente tendrá que haber sido escrito con esto en mente también.)

Otros consejos

¿Se puede utilizar MemoryMappedFiles ?

Si es posible, la cartografía del archivo en la memoria y compartirlo entre los procesos usted será capaz de leer los datos simplemente incrementando el desplazamiento para el puntero cada vez.

Si lo combinas con un evento que puede indicar su lector cuando puede ir en caso de leer la información. No habrá necesidad de bloquear cualquier cosa que el lector leerá siempre "viejos" datos que ya han sido escritas.

Yo recomendaría el uso de tuberías, actúan igual que los archivos, excepto datos de la corriente directa entre las aplicaciones, incluso si las aplicaciones se ejecutan en ordenadores diferentes (aunque esto en realidad es sólo una opción si usted es capaz de cambiar las dos aplicaciones). Comprobar que funciona bajo el espacio de nombres "System.IO.Pipes".

P.S. Se podría utilizar un tubo de "llamada" para esto (tubos están soportados en 'c', así que básicamente cualquier lenguaje de programación medio decente debe ser capaz de aplicarla)

Creo que (a) es la mejor, ya que:

  • Posición actual se incrementará a medida que lee y que no es necesario que preocuparse de almacenarlo en alguna parte;
  • No es necesario para abrirla y buscar la posición requerida (que no debería ser mucho más lento para volver a abrir, pero manteniéndolo abierto da OS algunos consejos para la optimización creo) cada vez que se sondea;
  • Otras soluciones que se me ocurren a cabo requiere PInvokes a las primitivas de sincronización entre procesos del sistema. Y no van a ser más rápido que las operaciones de archivos que ya están en marco.

Sólo tiene que establecer indicadores adecuados FileShare:

Sólo por ejemplo:

Servidor:

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
    }
}

Cliente:

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();
    }
}

también se puede transmitir los datos en una base de datos, en lugar de un archivo como otra alternativa, entonces no tiene que preocuparse por el bloqueo de archivos.

pero si le pegan con el método de archivo, es posible que desee cerrar el archivo cada vez que lea los datos de ella; que depende mucho de la complejidad del proceso de escritura en el archivo va a ser, y si se puede detectar un archivo de operación de bloqueo y responder adecuadamente sin que se caiga horrible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top