texto - leer y escribir archivos en c#
¿Cuál es la mejor manera de leer y analizar un archivo de texto grande en la red? (8)
Tengo un problema que me obliga a analizar varios archivos de registro desde una máquina remota. Hay algunas complicaciones: 1) El archivo puede estar en uso 2) Los archivos pueden ser bastante grandes (100mb +) 3) Cada entrada puede ser multilínea
Para resolver el problema en uso, necesito copiarlo primero. Actualmente estoy copiando directamente de la máquina remota a la máquina local y analizándolo allí. Eso lleva al problema 2. Dado que los archivos son bastante grandes, copiarlo localmente puede llevar bastante tiempo.
Para mejorar el tiempo de análisis, me gustaría hacer que el analizador tenga múltiples subprocesos, pero eso hace que manejar las entradas de múltiples líneas sea un poco más complicado.
Los dos problemas principales son: 1) ¿Cómo agilizo la transferencia de archivos? (¿Compresión? ¿Se está transfiriendo localmente incluso si es necesario? ¿Puedo leer un archivo en uso de otra forma?) 2) ¿Cómo trato las entradas de varias líneas? cuando se dividen las líneas entre los hilos?
ACTUALIZACIÓN: La razón por la que no hice el análisis obvio en la razón del servidor es que quiero tener el menor impacto de la CPU posible. No quiero afectar el rendimiento de la prueba de sistema del sistema.
Creo que usar compresión (desinflar / gzip) ayudaría
La manera más fácil considerando que ya está copiando el archivo sería comprimirlo antes de copiarlo y descomprimirlo una vez que se haya completado la copia. Obtendrá grandes ganancias al comprimir archivos de texto porque los algoritmos zip generalmente funcionan muy bien en ellos. Además, su lógica de análisis existente podría mantenerse intacta en lugar de tener que conectarla a un lector de texto de red remoto.
La desventaja de este método es que no podrá obtener actualizaciones línea por línea de manera muy eficiente, lo cual es bueno tener para un analizador de registros.
La mejor opción, desde la perspectiva del rendimiento, será realizar su análisis en el servidor remoto. Además de las circunstancias excepcionales, la velocidad de su red siempre será el cuello de botella, por lo que limitar la cantidad de datos que envía a través de su red mejorará enormemente el rendimiento.
Esta es una de las razones por las que muchas bases de datos usan procedimientos almacenados que se ejecutan en el extremo del servidor.
Las mejoras en la velocidad de análisis (si las hay) mediante el uso de subprocesamiento múltiple se verán inundadas por la velocidad comparativa de la transferencia de red.
Si se compromete a transferir sus archivos antes de analizarlos, una opción que podría considerar es el uso de la compresión sobre la marcha mientras realiza la transferencia de archivos. Hay, por ejemplo, servidores sftp disponibles que realizarán la compresión sobre la marcha. En el extremo local, puede usar algo como libcurl para hacer el lado del cliente de la transferencia, que también es compatible con la descompresión sobre la marcha.
Si está leyendo un archivo secuencial, quiere leerlo línea por línea en la red. Necesitas un método de transferencia capaz de transmitir. Tendrá que revisar su tecnología de transmisión IO para resolver esto.
Las operaciones de E / S grandes como esta no se beneficiarán mucho con el subprocesamiento múltiple, ya que probablemente pueda procesar los elementos tan rápido como pueda leerlos en la red.
Su otra gran opción es poner el analizador de registro en el servidor y descargar los resultados.
Si puedes copiar el archivo, puedes leerlo. Entonces no hay necesidad de copiarlo en primer lugar.
EDITAR : use la clase FileStream para tener más control sobre los modos de acceso y uso compartido.
new FileStream("logfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
debería hacer el truco.
Supongo que depende de qué tan "remoto" sea. 100MB en una LAN de 100Mb sería de aproximadamente 8 segundos ... hasta Gigabit, y lo tendrías en alrededor de 1 segundo. $ 50 * 2 para las tarjetas, y $ 100 para un cambio sería una actualización muy barata que podría hacer.
Pero, suponiendo que esté más alejado, debería poder abrirlo con el modo de solo lectura (como lo está leyendo cuando lo está copiando). SMB / CIFS es compatible con la lectura de bloque de archivos, por lo que debe transmitir el archivo en ese momento (por supuesto, no dijo realmente cómo estaba accediendo al archivo, estoy asumiendo SMB).
El subprocesamiento múltiple no ayudará, ya que de todos modos estará vinculado a un disco o red.
Use compresión para la transferencia.
Si su análisis realmente lo está desacelerando, y tiene múltiples procesadores, puede interrumpir el trabajo de análisis sintáctico, solo tiene que hacerlo de una manera inteligente: tenga un algoritmo determinista para el cual los trabajadores sean responsables de manejar registros incompletos. Asumiendo que puede determinar que una línea es parte de la mitad de un registro, por ejemplo, puede dividir el archivo en segmentos N / M, cada uno responsable de M líneas; cuando uno de los trabajos determina que su registro no está terminado, solo tiene que seguir leyendo hasta que llegue al final del registro. Cuando uno de los trabajos determina que está leyendo un registro para el que no tiene un comienzo, debe omitir el registro.
Utilicé SharpZipLib para comprimir archivos de gran tamaño antes de transferirlos a través de Internet. Entonces esa es una opción.
Otra idea para 1) sería crear un ensamblaje que se ejecute en la máquina remota y realice el análisis allí. Puede acceder al ensamblaje desde la máquina local utilizando .NET remoto. El ensamblaje remoto debería ser un servicio de Windows o alojarse en IIS. Eso le permitiría conservar sus copias de los archivos de registro en la misma máquina y, en teoría, tomaría menos tiempo procesarlas.