Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-10-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 17
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
si estas usando el codigo de daniel, la variable s es un string, los string (que es un alias de UnicodeString) en delphi si mal no recuerdo crecen hasta 2 gb, no sera ahi el problema?

archivos de 200mb no son muy grandes, yo hago la lectura usando el "old pascal i/o" y anda fenomenal, de hecho retroalimento la ui lo cual hace mas lento el procesamiento del archivo pero queda mas lindo

Es mas hasta incluso cometo la "estupides" de contar la cantidad de lineas para poder mostrar algo como "procesado x/CantLineas % completado"

Código Delphi [-]
// variables de instancia de la clase que procesa el archivo
strict private
    FCount: Integer;
    FTextFile: TextFile;
    FFilePath: string;

...
  AssignFile(FTextFile, FFilePath);

  try
    Reset(FTextFile);
    CountLines;
    { este seria el proceso contar lineas 
    procedure CountLines;
    begin
      FCount := 0;
      while not Eof(FTextFile) do
      begin
        Readln(FTextFile);
        Inc(FCount);
      end;
    end; }
    Reset(FTextFile);
    LCurrent := 0;

    Readln(FTextFile, LString);
    Inc(LCurrent);
    // procesar linea 
  finally
    CloseFile(FTextFile);
  end;

El archivo en cuestion tiene casi 200mb y unas 3,3 millones de lineas
El proceso de arriba en cuestion, incluyendo el conteo de lineas, el procesamiento interno, el guardado en la BD y teniendo en cuenta que retroalimenta la gui me demora unos 2, 3 min

Última edición por AgustinOrtu fecha: 30-10-2015 a las 06:27:16.
Responder Con Cita
  #2  
Antiguo 30-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Anel Hernandez

Como te menciona Agustín cuando los archivos son muy grandes es mas adecuado usar los procedimientos estandar de entrada/salida.
El método LoadFromFile de la clase TStrings, carga la totalidad del archivo en la memoria y luego lo divide en líneas, haciendo que se duplique el consumo de memoria y a veces puede provocar fragmentaciónes en la misma.

A cada variable de archivo de texto, Delphi le asigna un almacenamiento interno (buffer) de 128 bytes, por lo que usar el procedimiento SetTextBuff para modificar este valor, va a acelerar un poco el proceso.

Reproduje la situación con cuatro archivos de 228 Mb en este ejemplo:
Código Delphi [-]
...

procedure AppendTextFiles(const TargetName: TFileName;
  const SourceNames: array of TFileName);
var
  i      : Integer;
  source,
  target : TextFile;
  buffer : array[1..4096] of Char; 
  row    : string;
begin
  AssignFile(target, TargetName);
  // (*)
  try
    Reset(target);
  except
    ReWrite(target);
  end;
  // 
  Append(target);
  System.SetTextBuf(target, buffer);

  for i := Low(SourceNames) to High(SourceNames) do
  begin
    AssignFile(source, SourceNames[i]);
    Reset(source);
    System.SetTextBuf(source, buffer);
    while not Eof(source) do
    begin
      Readln(source, row);
      Writeln(target, row);
    end;
    Close(source);
  end;

  CloseFile(target);
end;


procedure TForm1.btnWritelnClick(Sender: TObject);
const
  MILLON = 1000000;
var
  Hz, Start, Stop: Int64;
begin
  QueryPerformanceFrequency(Hz);
  QueryPerformanceCounter(Start);

  AppendTextFiles('total.txt',['p1.txt', 'p2.txt', 'p3.txt', 'p4.txt']);
  QueryPerformanceCounter(Stop);

  ShowMessage(Format('%d µs.',[(Stop-Start) * MILLON div Hz]));
end;
Con un resultado en mi equipo de 76558319 µs ~ 76,55 s, tiempo mas que razonable.



(*): Si deseas que siempre se sobreescriba el archivo destino, reemplaza las lineas entre comentarios por:
Código Delphi [-]
ReWrite(target);

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 30-10-2015 a las 22:18:43. Razón: sintáxis
Responder Con Cita
  #3  
Antiguo 31-10-2015
Anel Hernandez Anel Hernandez is offline
Miembro
 
Registrado: mar 2005
Posts: 94
Poder: 22
Anel Hernandez Va por buen camino
hola,
estoy corriendo el ejemplo tal cual con 2 ficheros pequeños y con los nombres propuestos y da problemas.

no adiciona lineas, sobreescribe a partir de determinadas lineas adicionada comienza a reescribir lineas anteriores.

adjunto ficheros de ejemplo (p1.txt, p2.txt, total.txt).

sustitui el while por un ciclo de 77 lineas adicionadas y da bien (total77.txt). luego cuando lo intento con 78 da error (total78.txt). llegue a estos numeros por tanteo.

cual es el error?

gracias
A
Archivos Adjuntos
Tipo de Archivo: rar delp.rar (29,6 KB, 2 visitas)
Responder Con Cita
  #4  
Antiguo 01-11-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola Anel.

En este ejemplo quité todos los ornamentos, genera los 4 archivos de texto, los concatena en otro y muestra el archivo en un memo:
Código Delphi [-]
// Genera los cuatro archivos de texto de ejemplo
procedure TForm1.FormCreate(Sender: TObject);
var
  i, j: Integer;
  f: TextFile;
  s: string;
begin
  for i:= 1 to 4 do
  begin
    AssignFile(f, Format('p%d.txt', [i]));
    ReWrite(f);
    s := StringOfChar(Chr(96+i), 40);  // a, b, c, d
    for j := 1 to 5 do Writeln(f, s);
    CloseFile(f);
  end;
end;

// Concatenar sobreescribiendo
procedure AppendTextFiles(const TargetName: TFileName;
  const SourceNames: array of TFileName);
var
  i      : Integer;
  source,
  target : TextFile;
  row    : string;
begin
  AssignFile(target, TargetName);
  Rewrite(target);
  Append(target);
  for i := Low(SourceNames) to High(SourceNames) do
  begin
    AssignFile(source, SourceNames[i]);
    Reset(source);
    while not Eof(source) do
    begin
      Readln(source, row);
      Writeln(target, row);
    end;
    Close(source);
  end;
  CloseFile(target);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   AppendTextFiles('total.txt', ['p1.txt', 'p2.txt', 'p3.txt', 'p4.txt']);
   Memo1.Lines.LoadFromFile('total.txt');
end;

Salida del ejemplo:
;
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 01-11-2015
Anel Hernandez Anel Hernandez is offline
Miembro
 
Registrado: mar 2005
Posts: 94
Poder: 22
Anel Hernandez Va por buen camino
hola,

el ejemplo funciona perfectamente. El anterior logre que funcionara comentando la linea:
Código Delphi [-]
System.SetTextBuf(source, buffer);

luego cambie las variables buffer y quedo como:
Código Delphi [-]
System.SetTextBuf(target, buffer1);
...
System.SetTextBuf(source, buffer2);

ya todo OK. 23 segundos y todo OK.

gracias
A
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Borrar una parte de un TStringList eennzzoo C++ Builder 2 28-06-2014 14:04:13
copiar el contenido de un TStringList a TSringGrid GerTorresM Varios 1 02-07-2010 18:38:41
copiar la parte seleccionada de un imagen fasthorse C++ Builder 4 14-05-2008 20:05:03
Copiar parte de la pantalla.... craven Gráficos 2 27-08-2003 22:53:01
Copiar Parte de un BMP a otro craven API de Windows 1 07-07-2003 10:45:34


La franja horaria es GMT +2. Ahora son las 00:55:34.


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