Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Pasar ficheros binarios a texto (https://www.clubdelphi.com/foros/showthread.php?t=44200)

PTW 30-05-2007 22:50:44

Pasar ficheros binarios a texto
 
Hola a todos!!

Necesito hacer un programa que lea un ficheros binario del disco duro y cree un fichero de texto con su contenido. Del contenido fichero binario no sé ninguna información en cuanto a la estructura que tiene

al no conocer la estrcutra que tiene, ¿debo leerlo byte a byte, o con un TFileStream?

¿Me podeis echar un cable u orientarme un poco?

Muchas gracias

cHackAll 30-05-2007 23:24:41

Ok
 
Debes realizar una lectura byte por byte, cuando encuentres un caracter de texto ['a'..'z', 'A'..'Z', ' ', '.'..... etc ....'?'] debes verificar si los siguientes N (por ejemplo 4) caracteres tambien son texto, en tal caso escribes esos N bytes en otro archivo... no olvides inclur el #13#10.

Suerte!

seoane 30-05-2007 23:31:48

No entiendo muy bien lo que necesitas, pero aquí te dejo un código que puede que te sirva:

http://www.clubdelphi.com/foros/show...71&postcount=2

cHackAll 31-05-2007 00:03:05

Solucion
 
Creo que te es mas util el siguiente código... use pura API porque me gusta. Para las cadenas Unicode debes contar como un caracter si, un 0, otro si otro 0, etc, etc... para aumentar el "rango" cambia agrega contenido a la func. IsLetter.

Código Delphi [-]
function IsLetter(const Char: System.Char): LongBool;
begin
 Result := Char in ['a'..'z', 'A'..'Z', '0'..'9', ' '];
end;

const CrLf: Word = $0A0D;
var hFile, Index, Size, Dummy: Cardinal; lpBuffer: PChar;
begin
 hFile := CreateFile('c:\ntldr', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
 lpBuffer := MapViewOfFile(CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil), FILE_MAP_READ, 0, 0, 0);
 Size := GetFileSize(hFile, nil);
 CloseHandle(hFile);

 hFile := CreateFile('c:\ntldr.txt', GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
 Index := 0;
 while Index < Size do
  begin
   if ((Size - Index) > 3) and
      IsLetter(lpBuffer[Index]) and
      IsLetter(lpBuffer[Index + 1]) and
      IsLetter(lpBuffer[Index + 2]) and
      IsLetter(lpBuffer[Index + 3]) then
    begin
     while (Index < Size) and IsLetter(lpBuffer[Index]) do
      begin
       WriteFile(hFile, lpBuffer[Index], 1, Dummy, nil);
       Inc(Index);
      end;
     WriteFile(hFile, CrLf, 2, Dummy, nil);
    end
   else
    Inc(Index);
  end;
 CloseHandle(hFile);
end;

Espero te sirva.
Suerte!

PTW 31-05-2007 00:18:10

Pues son unos ficheros que genera un programa (tienen extensión .B00). Si lo intentas abrir con un editor de texto aparecen caracteres extraños, no se puede leer. Y necesito generar un fichero de texto, y escribir el contenido de ese fichero en codigo Ascii.

ArdiIIa 31-05-2007 00:23:59

Cita:

Empezado por PTW
Del contenido fichero binario no sé ninguna información en cuanto a la estructura que tiene
///////////
Pues son unos ficheros que genera un programa (tienen extensión .B00). Si lo intentas abrir con un editor de texto aparecen caracteres extraños, no se puede leer. Y necesito generar un fichero de texto, y escribir el contenido de ese fichero en codigo Ascii.

Pues dado que no puedes aportar mucho sobre el asunto, antes de comenzar con algoritmo alguno, también deberías considerar que el programa tiene su propio formato e incluso, porque no, tal vez codifique esos ficheros para que nadie los pueda leer.

Ese programa tiene nombre ?
Sirve para algo en concreto ?
Solamente procesa texto ?

En fin son unas cuestiones dignas de tener en cuenta antes de leer Ascii ¿No crees?

cHackAll 31-05-2007 03:23:12

Asi es!
 

Cita:

Empezado por ArdiIIa
...
Ese programa tiene nombre ?
Sirve para algo en concreto ?
Solamente procesa texto ?
...

Concuerdo con ArdiIIa, lo peor del asunto es que revisando éste link dice que es un gráfico!!!

Es un archivo pequeño? por que no lo comprimes y lo subes para ver si te podemos ayudar? y porfavor explicanos bien!

Saludos

PTW 31-05-2007 18:56:32

1 Archivos Adjunto(s)
Hola de nuevo. Perdon por el retraso en contestar.

Efectivamente, esos ficheros con extensión B00 contienen información sobre imágenes. Es un programa sobre copias digitales de fotografias

Del fichero en cuestion, me interesa sacar la informacion de los nombres de los JPG (fotos) que contiene, y las copias de cada foto. Pero bueno, en principio sacando los nombres de los jpgs que contiene el fichero B00 me vendría muy bien

Os subo un fichero de pruebas, porque veo que me explico como el culo :)

Gracias

cHackAll 31-05-2007 21:39:14

Entonces...
 
Bueno en ESE caso te dejo mi misma funcion un poco modificada:

Código Delphi [-]
function GetCardinal(var Buffer): Cardinal;
asm
 mov eax, [eax]
end;
 
const CrLf: Word = $0A0D;
var hFile, Index, Size, Count, Dummy: Cardinal; lpBuffer: PChar;
begin
 hFile := CreateFile('c:\250.b00', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
 lpBuffer := MapViewOfFile(CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil), FILE_MAP_READ, 0, 0, 0);
 Size := GetFileSize(hFile, nil);
 CloseHandle(hFile);
 hFile := CreateFile('c:\FileNames.txt', GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
 Index := 0;
 while Index < Size do
  begin
   if GetCardinal(lpBuffer[Index]) = $67706A2E then // '.jpg'
    begin
     Count := 0;
     while lpBuffer[Index - Count - 1] in ['a'..'z', 'A'..'Z', '0'..'9'] do Inc(Count);
     WriteFile(hFile, lpBuffer[Index - Count], Count + 4, Dummy, nil);
     WriteFile(hFile, CrLf, 2, Dummy, nil);
     Inc(Index, 4);
    end
   else
    Inc(Index);
  end;
 CloseHandle(hFile);
end;

Si no te saca todos los nombres es porque hay algunos Unicode, en ese caso nos comentas!

Suerte & Saludos!

cHackAll 31-05-2007 22:16:44

Me olvidaba decirte...
 
Me olvidaba! el archivo que subiste tiene muchos espacios! lo guardaste con Bloc de notas verdad????
Si es el caso NO lo vuelvas a hacer pues la ayuda que te den puede no servirte siempre para todos los casos!

Saludos!

PTW 31-05-2007 22:52:59

Hola cHackAll!!
Muchas gracias tio. Con esto espero que me ayude a sacar el resto de información que necesito. Por si acaso, no te vayas muy lejos :)

El fichero viene así, tal como lo he subido.

Saludos. Y gracias de nuevo

PD: En vez de cHackAll, te deberias llamar cHacracK, o yatá ( de lo rapido que lo has hecho) :)

cHackAll 31-05-2007 23:46:34

De nada
 
Es un placer ayudarte amigo, mediante evolucione tu sistema y necesitas ayuda nos escribes un post cuando lo necesites, pero procura cuidar tu lexico ok? no estoy muy de acuerdo con la palabrilla que acabo de leer pues no es muy comun en los foros.

Cita:

Empezado por PTW
...Os subo un fichero de pruebas, porque veo que me explico como el !$"%

Un saludo.

PTW 01-06-2007 10:25:10

Ok, no te preocupes. No volverá a pasar.

Una cosa sobre el código que has mandado:

Supongo que "$67706A2E
" es la representación en Hexadecimal de la tabla Ascii de la cadena ".jpg" ¿no?.

Pero he intentado buscar una cadena que empieza por "ID" (ya que me interesa el valor que tiene viene a continuación: ejemplo ID10)

Pero al hacer:
Código Delphi [-]if GetCardinal(lpBuffer[Index]) = $4449 then // 'ID'

nunca entra en ese if

¿Que es lo que estoy haciendo mal?
¿De donde sacas la representación de cada caracter? ¿de la tabla Ascii?

Saludos









cHackAll 01-06-2007 21:56:22

Ok
 
Cita:

Empezado por PTW
...Supongo que "$67706A2E" es la representación en Hexadecimal de la tabla Ascii de la cadena ".jpg" ¿no?.

Exactamente!

Cita:

Empezado por PTW
...Pero he intentado buscar una cadena que empieza por "ID" (ya que me interesa el valor que tiene viene a continuación: ejemplo ID10)

Debes tener MUY en cuenta que esta funcion que hice, encuentra '.jpg' y recorre luego hacia atras para copiar todo el nombre!

Cita:

Empezado por PTW
...Pero al hacer:
if GetCardinal(lpBuffer[Index]) = $4449 then // 'ID'
nunca entra en ese if

por supuesto, la funcion GetCardinal retorna una variable de 32 bits (4 bytes), de estos solo necesitas 2... entonces con:

Código Delphi [-]
if Word(GetCardinal(lpBuffer[Index])) = $4449 then
solucionas el problema, te lo dejo misma funcion un poco mejorada por si las dudas:

Código Delphi [-]
function GetCardinal(var Buffer): Cardinal;
asm
 mov eax, [eax]
end;
 
const CrLf: Word = $0A0D;
var hFile, Index, Size, Count, Dummy: Cardinal; lpBuffer: PChar; Found: LongBool;
begin
 hFile := CreateFile('c:\250.b00', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
 if hFile = INVALID_HANDLE_VALUE then
  begin
   MessageBox(0, 'No se puede acceder al archivo!', nil, MB_ICONEXCLAMATION);
   Exit;
  end;
 lpBuffer := MapViewOfFile(CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil), FILE_MAP_READ, 0, 0, 0);
 Size := GetFileSize(hFile, nil);
 CloseHandle(hFile);
 hFile := CreateFile('c:\FileNames.txt', GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
 Index := 0;
 Found := False;
 while Index < Size do
  begin
   if not Found and (Word(GetCardinal(lpBuffer[Index])) = $4449) then // 'ID'
    begin
     Count := 1;
     Inc(Index, 2);
     while lpBuffer[Index + Count] in ['0'..'9'] do Inc(Count);
     WriteFile(hFile, lpBuffer[Index], Count, Dummy, nil);
     WriteFile(hFile, CrLf, 2, Dummy, nil);
     WriteFile(hFile, CrLf, 2, Dummy, nil);
     Inc(Index, Count);
     Found := True;  // No debemos volver a antrar acá, pues puede haber algun nombre de archivo con ID
    end
   else
    if GetCardinal(lpBuffer[Index]) = $67706A2E then // '.jpg'
     begin
      Count := 0;
      while lpBuffer[Index - Count - 1] in ['a'..'z', 'A'..'Z', '0'..'9'] do Inc(Count);
      WriteFile(hFile, lpBuffer[Index - Count], Count + 4, Dummy, nil);
      WriteFile(hFile, CrLf, 2, Dummy, nil);
      Inc(Index, 4);
     end
    else
     Inc(Index);
  end;
 CloseHandle(hFile);
end;

Así y todo me queda la duda de que si los archivos pueden contener el nombre 'ID', en ese caso sirve la variable 'Found'
Además hay la posiblidad de que todos los archivos tengan ESE dato en una posicion fija, pero en todo caso la funcion anterior sirve.

Suerte!


La franja horaria es GMT +2. Ahora son las 13:19:17.

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