PDA

Ver la Versión Completa : Leer fichero de texto con problemas


sur-se
29-05-2008, 18:22:21
Hola.
Tengo un fichero de texto bastante grande (con cientos de megas) y quiero ejecutarle un procesado para eliminar una serie de caractares por debajo del ascii 32 que se han colado. El problema es que si utilizo el código siguiente:


var
f:textfile;
...
AssignFile(F, 'c:\mifich.txt');
Reset(F);
while not eof(f) do
begin
Readln(F, S);
procesar(s);
end;
CloseFile(F);


El fichero no se procesa completamente, ya que llega un momento en que uno de esos caracteres ascii que se han colado debe ser el fin de fichero y se para.
Si abro el fichero con el editor del delphi, por ejemplo, se lee completamente todo el fichero sin problemas, pero si lo abro con el wordpad, entonces sólo llega hasta donde está ese caracter.
Lo que quiero es procesarlo entero para eliminar esos caracteres por debajo del ascii 32, pero sin eliminar los saltos de línea para que siga como estaba.

¿alguna recomendación?

maeyanes
29-05-2008, 18:26:35
Hola...

Ya probaste cargarlo en un StringList?


var
Fichero: TStringList;
I: Integer;

begin
Fichero := TStringList.Create;
try
Fichero.LoadFromFile('c:\mifich.txt');
for I := 0 to Pred(Fichero.Count) do
Procesar(Fichero[I]);
// Si deseas guardar el fichero procesado:
Fichero.SaveToFile('c:\mifichproc.txt')
finally
Free
end
end;


Saludos...

sur-se
29-05-2008, 18:37:12
Hola. Si, ya lo intenté. A parte de que se queda pillado pues tiene que meter en memoria los 400 megas del fichero de texto, también se corta.
Lo ideal sería poder procesar línea a línea el fichero e ir grabándolo en otro, pero claro, sin que pare hasta que no se alcance el tamaño completo real.
Un saludo.

paladincubano
29-05-2008, 18:40:14
te recomiendo que pongas un Application.ProcessMessage dentro del While, incrementes una variable ejemplo <Linea> y la pongas en un Label para que vayas viendo por cual linea va procesando y mires donde se detiene y puedas ver si hay algun problema.

paladincubano
29-05-2008, 18:48:37
Otra cosa.
Recuerda que ReadLn lee una linea hasta que se encuentra un fin de linea.
Si este es muy grande pueda que no te quepa dentro de los limites de un String.
Por eso te sugiero que lo hagas con buffer.
Hay varios ejemplo de leer un fichero con buffer. Y vas procesando cada caracter.
Este puede ser un ejemplo


procedure TForm1.Cargar(Source, Destination: string);
var FromF, ToF: file of byte;
Buffer: array[0..4096] of char;
NumRead: integer;
FileLength: longint;
begin AssignFile(FromF, Source);
reset(FromF);
AssignFile(ToF, Destination);
rewrite(ToF);
FileLength := FileSize(FromF);
with Progressbar1 do begin Min := 0;
Max := FileLength;
while FileLength > 0 do begin BlockRead(FromF, Buffer[0], SizeOf(Buffer), NumRead);
FileLength := FileLength - NumRead;
..
//Aqui processas el Buffer con un ciclo de 0 a 4096 y cambias
//los caracteres que desees.
//ejem. if Buffer[i]<#32 then Buffer[i]=' ';
..
BlockWrite(ToF, Buffer[0], NumRead);
Position := Position + NumRead;
end;
CloseFile(FromF);
CloseFile(ToF);
end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin Cargar('c:\fileoriginal.txt', 'c:\nuevofile.txt');
end;



Espero te sirva, si tiene error, perdona, pero es que lo he hecho con un ejemplo de una copia de ficheros, pero puede servirte cualquier cosa dispara que estamos aqui.
saludos
Editado: Recuerda en la condicion decirle que si el caracter es #13 o #10 que no lo reemplazca, ya que son los caracteres de salto de linea. ;)
Hat un progressbar que puedes quitar, Es para que veas por donde va la edicion del fichero

sur-se
30-05-2008, 08:04:30
Hola. Gracias por las respuestas pero ya intenté también eso. El problema es la instrucción Filesize me devuelve el tamaño incorrecto del fichero, sólo hasta donde se encuentra ese caracter de fin de fichero.
Respecto a procesarlo y ver donde se corta. Esa es la cuestión. A mano si lo hago, claro, abro el fichero en Delphi (que me lo abre entero) y proceso con el programa que he hecho hasta la línea en la que existe un caracter de ese tipo. Vuelo al delphi, me voy a esa línea y borro ese caracter (bueno en delphi aparece como un cuadradito). Grabo el fichero y le vuelvo a dar al programa. Así sucesivamente. Lo que quiero es que esto sea automático pues son un montón de veces las que aparece el "EOF" por el fichero y no quiero hacerlo manualmente.
A ver si preparo un fichero de ejemplo con varias líneas y caracteres de corte y lo pongo aquí para que lo veais.
Gracias por la ayuda.

cHackAll
30-05-2008, 14:39:57
Hola (http://www.clubdelphi.com/foros/showthread.php?t=53125)