Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Busqueda de un string a lo largo de un TFileStream. (https://www.clubdelphi.com/foros/showthread.php?t=47368)

MaxiDucoli 25-08-2007 20:38:23

Busqueda de un string a lo largo de un TFileStream.
 
Hola Foro!!!
Es mi primer post y ojala pueda escribir muchos mas.
Tengo un problema el cual no pude resolver por que mi experiencia en Delphi aun no es mucha.
Lo que quiero hacer es ir leyendo un archivo, encotrar una cadena, guardar unos datos en una variable y seguir buscando esa cadena. Lo logre de una forma no muy convincente que digamos. Les paso a mostrar mi funcion a ver si pueden ayudarme.

Código Delphi [-]
Function BuscarVags (Archivo : String; const Cadena : string) : TStringList;
var
Arch : TFileStream;
buffer,texto : String;
Lista : TStringList;
Posicion : Integer;
Buf, Encontrado, ID, Offset : Integer;
Nombre : String;
begin
Lista := TStringList.Create;
Lista.Clear;
SetLength(Nombre,11);
Arch :=  TFileStream.Create(Archivo,FmOpenRead);
Buf := Arch.Size;
ID := 0;
SetLength(buffer,buf);
Arch.Position :=0;
Offset := Arch.position;
arch.Read(buffer[1],Length(buffer));

 // Encontrado:= POS(cadena,Buffer);
while Encontrado <> 0 do
begin

  Encontrado:= POSEx(cadena,Buffer,Offset);

Offset := Encontrado + 31;
            Arch.Position := Offset;
            Arch.Read(Nombre[1],Length(Nombre));
            Lista.Insert(ID,Nombre);
            //Lista := Nombre;
            //Lista.Cells[1,ID] := IntTostr(ID);
            ID := ID +1;


//            Arch.Position := Encontrado + 500;
//Archiv'

end;
         Result := TStringList(Lista);
         arch.Free;
          Lista.Delete(Lista.Count-1);
end;


Para utilizarla hago de la siguiente manera:
El ST es un St : TStringList.Create;

St := BuscarVags ('c:\Temporal\W2002j10.RA','VAGp');

Lo hace todo bien, lo que pasa es que el archivo que leo es de 40 MB y pueden llegar a ser mas grandes.
Mi idea principal era leer de a bloques de a 8192 bytes, pero la verdad es que no se como hacer para cuando termina el archivo, por que la variable OFFSET nunca va a llegar a ser mayor o igual al tamaño del archivo. No se me ingenio otra manera que esa y estuve tratando toda la noche. Si alguien es tan amable de aclararme las ideas por favor, la verdad, lo estoy necesitando.
Saludos! y muchas gracias.

xEsk 26-08-2007 00:46:28

Así por encima, el problema que le veo a leerlo por bloques, es que puedes tener la mala pata (debería ser muy mala pata, pero existe esta posibilidad xD) de que corte la frase que estas buscando, en 2 bloques diferentes... :s Y deberías controlar esto...

De forma rápida, creo que seria mejor buscarlo de golpe, pero ahí entra el inconveniente del tamaño del fichero, pero imagino que no seria problema cargar un fichero de 40 Mb o mas... ahí ya no me meto...

Cuando digo cargarlo todo de golpe, me refiero en cargarlo en un TStringList y hacer un Pos...

Ejemplo:

Código Delphi [-]
var
  FicheroTexto: TStringList;
  ...

begin
  ...
  Encontrado:=Pos(Cadena, FicheroTexto.Text) > 0;
  ...

Bueno, es lo máximo que puedo ayudarte en estos momentos.. hehe

Ah, y te recomiendo usar las etiquetas de código delphi, ayudarías mucho a que se entendiera el código, que leerlo así como lo has puesto da un poco de pereza...!

Saludos.

MaxiDucoli 26-08-2007 02:48:15

Lo que pasa es POS solamente te busca el primer valor.

Con POSEX le podes poner el offset en donde buscar, entonces si le hago una variable a buscar y despues el entero que me devuelve le sumo 1 me busca desde ahi en adelante.
Se que pudo cargar por bloques, leer, si no lo encuentro retroceder un poco dentro de la misma lectura, si no pasa nada que lea otro bloque y asi hasta encontrar.
Mi problema esta en que no se como hacer para finalizar el repeat UNTIL ¿¿¿QUE???? eso no se me ocurre de ninguna manera.
Ayuda please :)

paldave 26-08-2007 03:00:40

La verdad es que no entendí mucho que es lo que quieres hacer, ya que si buscas una cadena en el archivo y cuando la encuentras la guardas en una lista, cuando finalices tendrás una lista llena de la misma cadena que buscabas :confused:

No sé si yo soy tonto y no entendí, o no te expresaste bien, agradecería un ejemplo de lo que quieres hacer para poder ayudarte. :D

MaxiDucoli 26-08-2007 07:35:43

Cita:

Empezado por paldave (Mensaje 226154)
La verdad es que no entendí mucho que es lo que quieres hacer, ya que si buscas una cadena en el archivo y cuando la encuentras la guardas en una lista, cuando finalices tendrás una lista llena de la misma cadena que buscabas :confused:

No sé si yo soy tonto y no entendí, o no te expresaste bien, agradecería un ejemplo de lo que quieres hacer para poder ayudarte. :D




Bueno, tengo que buscar una palabra "VAGp" es la palabra, que corresponde al cabezal de muchos archivos de sonido de PlayStation.
Bueno, adentro del archivo hay como 300 vagp, entonces yo encuentro uno, la funcion POSEX me dice donde la encontro (en que OFFSET), yo guardo eso en la lista, y le digo a la funcion que busque otra vez por que la pongo en un repetir, pero le subo una posicion al offset para que no me encuentre lo mismo y asi sucesivamente hasta terminar el archivo. Pero eso en un Buffer de todo el archivo, y lo que yo quiero es hacerlo en pequeños trozos y no en un buffer del archivo completo.
Se entendio?

:confused::confused::confused::confused::confused::confused::confused::confused:

dec 26-08-2007 09:43:25

Hola,

En DelphiArea, entre otros, puede conseguirse el componente TFindFile, que, además de buscar archivos, es capaz de buscar en su interior. El procedimiento que se utiliza se me hace muy estudiado, muy bien hecho. Podrías estudiar el funcionamiento del mismo o bien utilizar el componente, directamente.

MaxiDucoli 26-08-2007 10:21:46

Muchas gracias, lo voy a investigar a ver como es. :)

b3nshi 26-08-2007 16:47:45

Viendo el codigo de este componente me surgieron unas dudas:

Q hacen estas lineas de codigo?

Código Delphi [-]
{$I DELPHIAREA.INC}
{$IFDEF COMPILER6_UP}
  {$WARN UNIT_PLATFORM OFF}
  {$WARN SYMBOL_PLATFORM OFF}
{$ENDIF}

Y por ejemplo cuando declara las constantes lo hace de la siguiente manera:

Código Delphi [-]
const
  FILE_ATTRIBUTE_SPARSE_FILE        = $00000200;
  {$IFDEF COMPILER4_UP}
  {$EXTERNALSYM FILE_ATTRIBUTE_SPARSE_FILE}
  {$ENDIF}
  FILE_ATTRIBUTE_REPARSE_POINT      = $00000400;
  {$IFDEF COMPILER4_UP}
  {$EXTERNALSYM FILE_ATTRIBUTE_REPARSE_POINT}
  {$ENDIF}
  FILE_ATTRIBUTE_ENCRYPTED          = $00004000;
  {$IFDEF COMPILER4_UP}
  {$EXTERNALSYM FILE_ATTRIBUTE_ENCRYPTED}
  {$ENDIF}

Porq :confused: y porq le da esos valores a las constantes :confused:

O si alguien me puede indicar q deberia leer para entenderlo mejor les estaria agradecidos...

{Saludos}

paldave 26-08-2007 17:05:55

Los valores dados a esas variables son para poder identificar luego los atributos del archivo con el cual se va a trabajar.
En cuanto a las líneas de código que te refieres son directivas para el compilador. Por ejemplo la directiva
Código Delphi [-]
{$I DELPHIAREA.INC}
indica al compilador que Incluya el archivo DELPHIAREA.INC, en tanto que la directiva
Código Delphi [-]
{$IFDEF COMPILER6_UP}
  {$WARN UNIT_PLATFORM OFF}
  {$WARN SYMBOL_PLATFORM OFF}
{$ENDIF}
se comporta como un condicional if then else, e indica al compilador que si la versión del compilador es 6 o superior (6_UP) entonces desactive (OFF) las advertencias (WARN) de exclusividad de plataforma de unidades (UNIT) y símbolos (SYMBOL), de tal forma que si usas un símbolo que es exclusivo de la plataforma en que estás trabajando (Windows, por ejemplo) el compilador no te advertirá de ello cuando realice la compilación (por defecto te lo advierte). Si el compilador es de una versión inferior a la 6 estas directivas no se procesarán, ya que no son necesarias porque estos compiladores no traían advertencias de plataforma y por lo tanto no tienen incluídas estas directivas.


La franja horaria es GMT +2. Ahora son las 14:15:27.

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