2011-05-09 18 views
13

Necesito leer en un archivo de texto sin formato de 1 gb del disco para ejecutar una manipulación de cadenas en C#.C# Manipulación de cadena muy grande (excepción de memoria agotada)

string contents = File.ReadAllText(path) 

es tirar de excepciones de memoria (como era de esperar)

¿Cuál es la mejor manera de hacer esto?

+4

¿Qué tipo de manipulación de cadenas? ¿Estaría bien leer solo algunas partes en un momento dado? –

+0

En teoría sí, pero trabajando con el código heredado y sé el entorno en el que se va a utilizar y sería más fácil leerlo de una vez. –

+0

Supongo que en realidad tiene suficiente RAM libre en la PC con la que está intentando hacer esto. Sé que modificar el código heredado puede ser doloroso (y atemorizante también si su misión es crítica), pero es posible que deba considerar simplemente leer un fragmento a la vez y trabajar con él de esa manera. –

Respuesta

12

Posiblemente también buscar en el uso de un memory-mapped file

+0

Desde los documentos parece que usaría un 'MemoryMappedViewStream' y luego extraería algunos trozos de bytes. Use 'Encoding.GetString' [http://msdn.microsoft.com/en-us/library/05cts4c3.aspx] si es necesario. – Dave

0

Si otros sugirieron solución no funciona, le sugiero que establecer un límite de caracteres para leer, y leer el texto por partes Una vez que almacena en caché una parte del texto, puede manipularlo.

Si necesidad manipular en cualquier dirección (quiero decir, no de izquierda a derecha en un solo paso), siempre se puede implementar un B-Tree y almacenar partes del texto en los nodos :)

A veces es casi imposible trabajar secuencialmente leyendo un texto por partes, y aquí es donde un árbol B ayuda. Lo implementé hace aproximadamente un año con fines académicos (un administrador de mini bases de datos), pero creo que debería haber implementaciones de este en C#. Por supuesto, deberá implementar cómo cargar los nodos de BTree desde el archivo.

7

Si realmente quieres hacer esto enorme manipulación de cadenas en la memoria, entonces no está fuera de suerte más, siempre se puede cumplir con los siguientes requisitos

  1. Compilar x64 focalización
  2. Ejecutar en un sistema x64
  3. Objetivo .NET 4.5

Esto eliminará todas las limitaciones de memoria que enfrenta. La memoria de su proceso estará limitada solo por la memoria de su computadora, y no hay un límite de 2GiB en un solo objeto .NET que comience en .NET 4.5 para x64.

0

Estaba usando ReadAllText para el archivo de 109 mb y me estaba quedando sin memoria, lo cual es realmente extraño. De todos modos, utilicé el búfer para leer archivos con buen rendimiento y StringBuilder para que sea eficiente desde el punto de vista de la memoria. Aquí está mi código:

   StringBuilder sb = new StringBuilder(); 
       using (FileStream fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
       using (BufferedStream bs = new BufferedStream(fs)) 
       using (StreamReader sr = new StreamReader(bs)) 
       { 
        string line;      
        while ((line = sr.ReadLine()) != null) 
         sb.AppendLine(line); 
       } 
Cuestiones relacionadas