Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Buscar cadena en un archivo binario (https://www.clubdelphi.com/foros/showthread.php?t=86833)

ZayDun 10-10-2014 13:53:46

Buscar cadena en un archivo binario
 
Hola, llevo un buen rato buscando información tanto en el foro como en google sobre editar archivos binarios y no encuentro la solución a lo que busco, os cuento por si me podéis ayudar.

tengo un archivo llamado "config.dat", lo he abierto con un editor de texto y aparecen caracteres codificados y entre ellos se encuentra la cadena que estoy buscando sin codificar, en principio mi idea era la de abrir, buscar, reemplazar y guardar, pero se me esta complicando el código para hacerlo, buscando por el foro encontré este código..

Código Delphi [-]
procedure TFPrincipal.AnadirStreamBinario;
var F: TFileStream;
    Buffer: array[0..1023] of byte;
    i, j: Integer;
    b: Byte;
begin
  F := TFileStream.Create( ExtractFilePath( Application.ExeName ) + 'prueba.dat', fmOpenWrite );
  F.Position := F.Size;

  b := 0;
  // Guardamos 100 veces el buffer de 1 KB (100 KB)
  for j := 1 to 100 do
  begin
    for i := 0 to 1023 do
    begin
      Buffer[i] := b;
      Inc( b );
    end;

    F.Write( Buffer, 1024 );
  end;

  F.Free;
end;

Pero ahora no se como hacer para buscar dentro del archivo la cadena que estoy buscando.

nlsgarcia 10-10-2014 16:07:16

ZayDun,

Cita:

Empezado por ZayDun
...Buscar cadena en un archivo binario...abrir, buscar, reemplazar y guardar...

:rolleyes:

Revisa esta información:
Te sugiero revisar específicamente el Msg #43.

Espero sea útil :)

Nelson.

ZayDun 10-10-2014 16:21:58

Cita:

Empezado por nlsgarcia (Mensaje 482875)
ZayDun,


:rolleyes:

Revisa esta información:
Te sugiero revisar específicamente el Msg #43.

Espero sea útil :)

Nelson.

Muchas gracias Nelson! llevaba toda la mañana buscando y haciendo pruebas, te agradezco mucho tu ayuda.

ZayDun 10-10-2014 18:05:13

Cita:

Empezado por nlsgarcia (Mensaje 482875)
ZayDun,


:rolleyes:

Revisa esta información:
Te sugiero revisar específicamente el Msg #43.

Espero sea útil :)

Nelson.


He copiado el código que me has facilitado tal y como esta y me copila sin problemas, ya he reemplazado la ruta y las cadenas hex y me lanza el mensaje "Cambio de Archivo Realizado" y me genera una copia exacta con la extensión *.new del archivo pero no modificada nada, he probado con diferentes rutas incluso con un archivo de texto plano, alguna idea de que puede ser?

Estoy utilizando Windows 7 64bit y la versión Delphi XE5.

nlsgarcia 10-10-2014 18:39:58

ZayDun,

Cita:

Empezado por ZayDun
...He copiado el código...pero no modificada nada...¿alguna idea de que puede ser?...

:rolleyes:

Te comento:

1- El código del Msg #43 del link sugerido, tiene dos funciones para el cambio de archivos a nivel Binario : ChangeFileHex y ChangeFileOffset las cuales, permiten cambiar una cadena hexadecimal en un archivo.

2- Función ChangeFileHex: Cambia n ocurrencias de una cadena hexadecimal por una nueva cadena hexadecimal en un archivo dado y salva los cambios en un nuevo archivo del mismo nombre del original con extensión .new, en el mismo directorio del archivo de entrada.

3- Función ChangeFileOffset: Sustituye en un Offset (Dirección en Decimal) de un archivo dado una cadena hexadecimal y salva los cambios en un nuevo archivo del mismo nombre del original con extensión .new, en el mismo directorio del archivo de entrada.

Los Bytes Per Row (BPF) de ambas funciones están en función de la longitud de la cadenas de entrada OldHex (Función ChangeFileHex) y NewHex (Función ChangeFileOffset), siendo importante recordar que ambas cadenas deben ser del mismo tamaño en las funciones mencionadas.

Nota: Las dos funciones anteriores leen y modifican los archivos de entrada y salida directamente en disco, lo cual les permite procesar archivos de cualquier tamaño, limitados solo por las características del Sistema de Archivos del Sistema Operativo de forma rápida y eficiente e independientemente de cualquier componente de Delphi, funcionado correctamente según lo esperado en las pruebas realizadas.

Pregunto:

1- ¿Cual función utilizastes ChangeFileHex o ChangeFileOffset?.

2- ¿Has utilizado el programa HxD - Hexeditor para ubicar el offset de la cadena a modificar?.

Revisa con detalle todo lo anterior, si aun no te funciona, publica un link para descargar el archivo con el detalle de lo que quieres modificar y vere que puedo hacer
:D

Espero sea útil
:)

Nelson.

ZayDun 10-10-2014 20:15:38

Cita:

Empezado por nlsgarcia (Mensaje 482885)
ZayDun,


:rolleyes:

Te comento:

1- El código del Msg #43 del link sugerido, tiene dos funciones para el cambio de archivos a nivel Binario : ChangeFileHex y ChangeFileOffset las cuales, permiten cambiar una cadena hexadecimal en un archivo.

2- Función ChangeFileHex: Cambia n ocurrencias de una cadena hexadecimal por una nueva cadena hexadecimal en un archivo dado y salva los cambios en un nuevo archivo del mismo nombre del original con extensión .new, en el mismo directorio del archivo de entrada.

3- Función ChangeFileOffset: Sustituye en un Offset (Dirección en Decimal) de un archivo dado una cadena hexadecimal y salva los cambios en un nuevo archivo del mismo nombre del original con extensión .new, en el mismo directorio del archivo de entrada.

Los Bytes Per Row (BPF) de ambas funciones están en función de la longitud de la cadenas de entrada OldHex (Función ChangeFileHex) y NewHex (Función ChangeFileOffset), siendo importante recordar que ambas cadenas deben ser del mismo tamaño en las funciones mencionadas.

Nota: Las dos funciones anteriores leen y modifican los archivos de entrada y salida directamente en disco, lo cual les permite procesar archivos de cualquier tamaño, limitados solo por las características del Sistema de Archivos del Sistema Operativo de forma rápida y eficiente e independientemente de cualquier componente de Delphi, funcionado correctamente según lo esperado en las pruebas realizadas.

Pregunto:

1- ¿Cual función utilizastes ChangeFileHex o ChangeFileOffset?.

2- ¿Has utilizado el programa HxD - Hexeditor para ubicar el offset de la cadena a modificar?.

Revisa con detalle todo lo anterior, si aun no te funciona, publica un link para descargar el archivo con el detalle de lo que quieres modificar y vere que puedo hacer
:D

Espero sea útil
:)

Nelson.

El problema como casi siempre.. era mio, parece que se ha solucionado el problema dandole permisos de administrador, como te decía el código copilaba perfectamente pero no realizaba el cambio.

Tengo una última duda si fueses tan amable de contestarme, estoy utilizando la función ChangeFileHex y a veces el nombre de la cadena es mas largo que el de la original, hay alguna posibilidad de permitir que cambie independientemente del tamaño de la cadena? cuando realizo el cambio manualmente en el archivo no hay ningún problema con el archivo, es decir que no se vuelve corrupto. Gracias de nuevo por tu tiempo.

nlsgarcia 10-10-2014 20:55:20

ZayDun,

Cita:

Empezado por ZayDun
...estoy utilizando la función ChangeFileHex...¿Hay alguna posibilidad de permitir que cambie independientemente del tamaño de la cadena?...

:rolleyes:

Te comento:

1- Si es posible, la clave esta en tener dos Buffers : Uno de entrada y otro de salida.

2- Voy a hacer unos cambios a la función ChangeFileHex y cuando este listo lo publico :D

Pregunto:

1- ¿Cual es el objetivo de esta aplicación? :confused:

2- ¿El uso de la aplicación es a nivel comercial, académico o personal?.

3- ¿En que país se usara la aplicación?.

Espero sea útil :)

Nelson.

ZayDun 10-10-2014 21:12:27

Cita:

Empezado por nlsgarcia (Mensaje 482892)
ZayDun,


:rolleyes:

Te comento:

1- Si es posible, la clave esta en tener dos Buffers : Uno de entrada y otro de salida.

2- Voy a hacer unos cambios a la función ChangeFileHex y cuando este listo lo publico :D

Pregunto:

1- ¿Cual es el objetivo de esta aplicación? :confused:

2- ¿El uso de la aplicación es a nivel comercial, académico o personal?.

3- ¿En que país se usara la aplicación?.

Espero sea útil :)

Nelson.

Tengo un programa que al abrirlo trae los datos de configuración por defecto, el problema es que aunque cierre la aplicación con los nuevos datos el programa no los guarda y cada vez que lo abro tengo que volver a modificarlo todo, el archivo a modificar se guarda como config.dat y mi idea es que modifique la cadena y despues ejecute el programa.

El programa es para uso personal y el país es España.

nlsgarcia 10-10-2014 21:40:07

ZayDun,

Cita:

Empezado por ZayDun
...Tengo un programa que al abrirlo trae los datos de configuración por defecto...

:rolleyes:

Pregunto:

1- ¿A que programa te refieres?, ¿Cual es el objetivo de esa aplicación? :confused:

2- ¿Cuales son los datos de configuración por defecto de la aplicación en cuestión que quieres modificar?.

Espero sea útil :)

Nelson.

ecfisa 10-10-2014 23:22:21

Hola ZayDun.
Cita:

Empezado por ZayDun (Mensaje 482874)
...
tengo un archivo llamado "config.dat", lo he abierto con un editor de texto y aparecen caracteres codificados y entre ellos se encuentra la cadena que estoy buscando sin codificar, en principio mi idea era la de abrir, buscar, reemplazar y guardar, pero se me esta complicando el código para hacerlo,
...
Pero ahora no se como hacer para buscar dentro del archivo la cadena que estoy buscando.

En principio me siento obligado a comentarte que es una acción delicada, por lo que te recomiendo hacer una copia del archivo y realizar las pruebas sobre esta última.

Código Delphi [-]
procedure SearchAndReplace(const FileName: TFileName;
  const Searched, Replacement: string);
var
  Stream: TFileStream;
  i, cc : Integer;
  buf   : Char;
  start : Int64;
begin
  if Length(Searched) <> Length(Replacement) then
    raise Exception.Create('¡Las longitudes de las cadenas deben ser iguales!');

  Stream:= TFileStream.Create(FileName, fmOpenReadWrite);
  try
    cc   := 1;
    start:= -1;
    for i:= 0 to Stream.Size do
    begin
      Stream.Read(buf,SizeOf(buf));
      if cc-1 = Length(Searched) then
      begin
        start:= Stream.Position - Length(Searched)-1;
        Break;
      end;
      if buf = Searched[cc] then
        Inc(cc)
      else
        cc:= 1;
    end;
    Stream.Position:= start;
    for i:= 1 to Length(Searched) do
      Stream.Write(Replacement[i], SizeOf(buf));
  finally
    Stream.Free;
  end;
end;

Ejemplo de uso:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  SearchAndReplace('C:\pruebas\notepad2.exe',
    'This program cannot be run in DOS mode',
    'Este programa no ejecutara en modo DOS');
end;
Aunque probé el código y sé que realiza correctamente lo que buscas, insisto en que resguardes el original y trabajes sobre una copia. Hasta estar completamente seguro que la aplicación que usa ese archivo funcione después del cambio.

Saludos :)

nlsgarcia 11-10-2014 08:58:23

ZayDun,

Están pendientes las preguntas del Msg #9 :cool:

Nelson.


La franja horaria es GMT +2. Ahora son las 09:11:20.

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