Pregunta

En C # / .NET (en Windows) hay una manera de leer " creciendo " archivo utilizando una secuencia de archivos? La longitud del archivo será muy pequeña cuando se abra el flujo de archivos, pero otro hilo escribirá en el archivo. Si / cuando el flujo de archivos " se pone al día " a la otra cadena (es decir, cuando Read () devuelve 0 bytes leídos), quiero hacer una pausa para permitir que el archivo se almacene un poco en el búfer, luego continuar leyendo.

Realmente no quiero usar un FilesystemWatcher y seguir creando nuevas secuencias de archivos (como se sugirió para los archivos de registro), ya que no es un archivo de registro (es un archivo de video que se está codificando). sobre la marcha) y el rendimiento es un problema.

Gracias,
Robert

¿Fue útil?

Solución

Puede hacer esto, pero debe realizar un seguimiento cuidadoso de las posiciones de lectura y escritura del archivo utilizando Stream.Seek y con la sincronización adecuada entre los subprocesos. Por lo general, usaría un EventWaitHandle o una subclase del mismo para realizar la sincronización de los datos, y también debería considerar la sincronización para el acceso al objeto FileStream (probablemente a través de un lock sentencia).

Actualización: Al responder a esta pregunta implementé algo similar, una situación en la que un archivo se estaba descargando en segundo plano y también se estaba cargando al mismo tiempo. Usé buffers de memoria y publiqué un gist que tiene un código de trabajo. (Es GPL, pero eso puede no ser importante para usted, en cualquier caso, puede usar los principios para hacer lo suyo).

Otros consejos

La forma en que resolví esto es mediante el uso de DirectoryWatcher / FilesystemWatcher class, y cuando se dispara en el archivo que desea, abre un FileStream y lo lee hasta el final. Y cuando termine de leer, guardo la posición del lector, así que la próxima vez DirectoryWatcher / FilesystemWatcher se desencadena al abrir una ruta, establecer la posición en la que estaba la última vez.

La llamada a FileStream.length actualmente es muy lenta, no he tenido problemas de rendimiento con mi solución (estaba leyendo un "registro" que va de 10 a 50 ish).

Para mí, la solución que describo es muy simple y fácil de mantener, la probaría y la perfilaría. No creo que vayas a tener ningún problema de rendimiento basado en ello. Hago esto cuando las personas están jugando un juego de múltiples hilos, tomando todo su CPU y nadie se ha quejado de que mi analizador es más exigente que los analizadores de la competencia.

Esto funcionó con un StreamReader alrededor de un archivo, con los siguientes pasos:

  1. En el programa que escribe en el archivo, ábralo con lectura compartida, como esto:

    var out = new StreamWriter(File.Open("logFile.txt",  FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read));
    
  2. En el programa que lee el archivo, ábralo con el uso compartido de lectura-escritura, como este:

    using (FileStream fileStream = File.Open("logFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using ( var file = new StreamReader(fileStream))
    
  3. Antes de acceder a la secuencia de entrada, compruebe si se ha alcanzado el final y, si es así, espere un poco.

    while (file.EndOfStream)
    {
        Thread.Sleep(5);
    }
    

Otra cosa que podría ser útil es que la clase FileStream tiene una propiedad llamada ReadTimeOut que se define como:

Obtiene o establece un valor, en milisegundos, que determina cuánto tiempo intentará leer la secuencia antes de que se agote el tiempo de espera. (heredado de Stream)

Esto podría ser útil, ya que cuando sus lecturas se pongan al día con sus escrituras, el hilo que realiza las lecturas puede pausar mientras se descarga el búfer de escritura. Desde luego, valdría la pena escribir una pequeña prueba para ver si esta propiedad ayudaría a su causa de alguna manera.

¿Las operaciones de lectura y escritura ocurren en el mismo objeto? Si es así, puede escribir sus propias abstracciones sobre el archivo y luego escribir el código de comunicación entre hilos de manera tal que el hilo que está realizando las escrituras y notifique al hilo que realiza las lecturas cuando se hace para que el hilo que realiza las lecturas sepa cuándo parar de leer. cuando llega a EOF.

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