Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-08-2005
nax nax is offline
Miembro
 
Registrado: mar 2004
Posts: 52
Poder: 21
nax Va por buen camino
Procesando ficheros muy GRANDES

Qué tal, reciban un caluroso saludo. Tengo un problema y al momento no sé cómo resolverlo. Tengo archivos de texto muy, muy grandes (alrededor de 100 megas o más) y requiero procesarlos. El problema estriba en que no sé qué tantos bloques de texto (o caracteres) debo ir leyendo (o escribiendo) para que no se sature la memoria del ordenador, y para que los accesos al disco no sean muchos y el proceso sea lento. ¿Alguna sugerencia? Gracias!!!!

Última edición por nax fecha: 20-08-2005 a las 23:45:24.
Responder Con Cita
  #2  
Antiguo 21-08-2005
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.107
Poder: 34
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Con más voluntad de ayudar que otra cosa se me ha ocurrido que tal vez pudieras procesar el archivo a trozos. Bien es verdad que de la manera en que se me ha ocurrido, como digo, primero tendrías que leer todo el archivo de una vez, pero no parece haber demasiados problemas: he probado con un archivo de texto que he creado con el NotePad costándome lo suyo, pues al cabo he conseguido que este contuviera más de 50 MB de texto.

Una vez cargado el archivo en una variable de tipo "TStream", he pensado en ir leyéndolo poco a poco, guardando cada "trozo" en una variable de tipo "TStreamString". Como la "secuencia" se realiza en un bucle "repeat", a cada paso por dicho bucle se contaría con un trozo del archivo, de los bytes que precisáramos en el "buffer" que preparamos para ir leyendo el contenido del archivo.

El tema está en que "la cosa" se desarrolla con bastante rapidez y, tal como podrás ver, sin que la interfaz sufra y se quede congelada, como suele decirse. Pero (hay más de un pero, este solo es uno de ellos) se me ocurre que tendrías problemas para procesar cada trozo del archivo en cuestión, puesto que tal vez no obtengas en los trozos "lo necesario" para poder procesarlo correctamente.

En definitiva, no sé si lo que he hecho, repito, con más voluntad de ayudar que otra cosa, ya lo habrías pensado tú, y, encuentras el mismo problema que refiero arriba, de cómo ajustar "los trozos" para que estos puedan ser procesados correctamente.

Bueno. El poco de código que he escrito es el siguiente:

Código Delphi [-]
  procedure ProcesarArchivo(rutArchivo: string);
  var
   stream: TStream;
   leidos: Cardinal;
   trozos: TStringStream;
   buffer: array [0..2048] of byte;
  begin
   stream := TFileStream.Create(rutArchivo, fmOpenRead);
   leidos := stream.Read(buffer, SizeOf(buffer));
   repeat
     Application.ProcessMessages;
     trozos := TStringStream.Create('');
     trozos.WriteBuffer(buffer, leidos);
     {
        trozos.DataString; ...
  
        Contiene los últimos 2048 bytes
        leídos del archivo en proceso.
     }
     leidos := stream.Read(buffer, SizeOf(buffer));
     trozos.Free;
   until (leidos = 0);
   stream.Free;
  end;
Si alguien puede corregir algo que no tarde en hacerlo. Se le agradecerá. Y, si he podido ser de utilidad en algo, pues mira tú qué bien. Y, si no he podido, pues lo siento. Otra vez será.

Actualización: Caramba, ahora me entero de que planteaste la cuestión en el Foro de C++ Builder... y yo pensando que era el de Delphi respondí como se puede ver... bueno, cabe que no sea demasiado complicado, si es que sirve de algo lo que he propuesto, hacer lo propio en C++ Builder, traduciendo de Delphi.
__________________
David Esperalta
www.decsoftutils.com

Última edición por dec fecha: 21-08-2005 a las 10:49:27. Razón: (actualización)
Responder Con Cita
  #3  
Antiguo 22-08-2005
nax nax is offline
Miembro
 
Registrado: mar 2004
Posts: 52
Poder: 21
nax Va por buen camino
Caramba!! Agradezco enormemente el tiempo que has invertido al atender mi duda. Aún no implemento lo que has indicado, pues estoy primero revisando que el proceso que hago a los datos son correctos, para enseguida escribirlos y leerlos. En cuanto haya terminado de verificar estas cosas, haré saber los resultados. Saludos y nuevamente mil gracias.


PD.
Jejeje, sí, noté que lo que habías señalado es para delphi. No hay problema, es legible. Gracias .
Responder Con Cita
  #4  
Antiguo 23-08-2005
nax nax is offline
Miembro
 
Registrado: mar 2004
Posts: 52
Poder: 21
nax Va por buen camino
Qué tal! Pues ya implementé lo que me has dicho, más un par de líneas para asegurar que los bloques obtenidos contengan cadenas no truncadas. Manejando bloques de 2048 bytes he obtenido alrededor de 4 megas de texto procesados en 8 minutos, por lo que más adelante probaré aumentando dicho bloque al doble o triple, según vaya viendo qué pasa con los recursos de mi Lentium.

La implementación en C++ Builder:

Código:
ifstream in;	// Flujo de lectura
ofstream out; // Flujo de escritura
const int blockSize = 2048;
char buffer[blockSize], faltante[256];
String bloque, ruta = ExtractFileDir (Application->ExeName) + "\\OUT.txt",
		 procesado = ""; // almacenará resultados del procesamiento
 
in.open (edtFuente->Text.c_str()); // Archivo a leer
out.open (ruta.c_str());				// Archivo de resultados
 
if (!in || !out) // No se pudo alguno de ellos abrir...
{
// Mostrar algo
}
else
{
   while (!in.eof())
   {
	 in.read (buffer, blockSize); // Leer los 2048 bytes
 
	 bloque = buffer; // Convirtiendo a String para mejor manejo
 
	 // Asegurándome de que el bloque no quede truncado...
	 in.getline(faltante, 256, ' '); 
	 // Leo hasta el siguiente espacio en blanco o 256 caracteres
	 // (una palabra por muy larga no sobrepasa 15 o 20)
 
	 bloque += faltante; // concateno al bloque
 
	 // Procesando el bloque
	 while (!bloque.IsEmpty())
	 {
		 // ...
	 }
 
	 // Escribo texto procesado en archivo
	 out.write(procesado.c_str(), procesado.Length());
   }
in.close();
}
Bien, así ha sido como he manejado este asunto. Si alguien tiene otra manera más eficiente de manejar ésto no tarde en compartirla Saludos y gracias.

Última edición por nax fecha: 23-08-2005 a las 20:07:35.
Responder Con Cita
  #5  
Antiguo 26-08-2005
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
No lo he probado pero que tal esto?

http://xdelphi.xtort.net/data/BigFileRead.html
__________________
El malabarista.
Responder Con Cita
  #6  
Antiguo 27-08-2005
nax nax is offline
Miembro
 
Registrado: mar 2004
Posts: 52
Poder: 21
nax Va por buen camino
Qué tal! Aún no checo lo del último hilo, pero por ahí me comentaron "con la velocidad de procesamiento de las pc's actuales, puedes leer tu archivo línea a línea y no se demorará casi nada". No me gustó nada el "consejo", pues creo que un programador siempre debe realizar de manera eficiente sus programas. Pero lo probé... y reconozco que tienen razón. Un archivo de 100 megas procesado línea a línea no demoró más de dos minutos (lo corrí en otro equipo un poco más actual comparado con el de mi último hilo)...

Última edición por nax fecha: 27-08-2005 a las 02:15:57.
Responder Con Cita
  #7  
Antiguo 27-08-2005
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.039
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Actualmente estoy acabando un pequeño proyecto que, resumiendo, sirve para enviar información entre tiendas, sucursales y la central de la empresa. Se usa un servidor FTP y los datos son archivos de texto, normales, con campos separados por tabulador y fin de linea, van comprimidos y encriptados. Pero lo que quiero comentarte es que estos archivos de texto ocupan varios gigas y la velocidad de proceso es muy buena, la cpu no se satura, gran parte del trabajo lo hace el disco (leer y escribir), así que cuando está procesando datos, los usuarios no lo notan en sus terminales.
He usado lo "normal" con delphi, un TextFile, abierto con AssignFile, leer con ReadLn, escribir con WriteLn, etc... y no hay problemas de alto consumo de memoria, lentitud, ni nada... aunque, eso sí, importar varios gigas de datos sí que lleva su tiempo para insertarlos en la base de datos (firebird) de la central
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 11:01:34.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi