본문 바로가기

Delphi

[Delphi] File Binary 관련 함수


interface

uses
  SysUtils, ConvertHex;

procedure PutHex(filepath: string; hexs: string; offset: integer); overload;
Procedure PutHex(filepath: string; arr: byDynamicArr; offset: integer); overload;
procedure InsertHex(filepath: string; hexs: string; offset: integer); overload;
procedure InsertHex(filepath: string; arr: byDynamicArr; offset: integer); overload;
procedure RemoveHex(filepath: string; offset: integer; count: integer);
function ReadHex(filepath: string; offset: integer; count: integer): byDynamicArr;
function GetFileSize(filepath: string): integer;
function ReadByte(filepath: string; offset: integer): byte;
function ReadWord(filepath: string; offset: integer): integer;
function ReadInt(filepath: string; offset: integer): integer;

implementation

uses
  frm_main;

function GetFileSize(filepath: string): integer;
var
  Srec: TSearchRec;

begin
  if findfirst(filepath, faAnyFile, Srec) = 0 then
    Result := Srec.Size
  else
    Result := 0;
end;

Procedure PutHex(filepath: string; hexs: string; offset: integer); overload;
var
  f: file;
  arr: byDynamicArr;

begin
  arr := hextobytearr(hexs);

  assignfile(f, filepath);
  reset(f, 1);
  seek(f, offset);
  blockwrite(f, arr[0], high(arr) + 1); // Arr[0] is right, not Arr. Because of Dynamic Array.
  closefile(f);
end;

Procedure PutHex(filepath: string; arr: byDynamicArr; offset: integer); overload;
var
  f: file;

begin
  assignfile(f, filepath);
  reset(f, 1);
  seek(f, offset);
  blockwrite(f, arr[0], high(arr) + 1); // Arr[0] is right, not Arr. Because of Dynamic Array.
  closefile(f);
end;

procedure InsertHex(filepath: string; hexs: string; offset: integer); overload;
var
  f: file;
  arr: byDynamicArr;
  temparr: byDynamicArr;

begin
  arr := hextobytearr(hexs);

  assignfile(f, filepath);
  reset(f, 1);

  setlength(temparr, filesize(f) - offset);

  // Read
  seek(f, offset);
  blockread(f, temparr[0], high(temparr) + 1);

  // Insert
  seek(f, offset);
  blockwrite(f, arr[0], high(arr) + 1);
  seek(f, offset + high(arr) + 1);
  blockwrite(f, temparr[0], high(temparr) + 1);

  closefile(f);
end;

procedure InsertHex(filepath: string; arr: byDynamicArr; offset: integer); overload;
var
  f: file;
  temparr: byDynamicArr;

begin
  assignfile(f, filepath);
  reset(f, 1);

  setlength(temparr, filesize(f) - offset);

  // Read
  seek(f, offset);
  blockread(f, temparr[0], high(temparr) + 1);

  // Insert
  seek(f, offset);
  blockwrite(f, arr[0], high(arr) + 1);
  seek(f, offset + high(arr) + 1);
  blockwrite(f, temparr[0], high(temparr) + 1);

  closefile(f);
end;

procedure RemoveHex(filepath: string; offset: integer; count: integer);
var
  f: file;
  tempbeginarr: byDynamicArr;
  tempendarr: byDynamicArr;

begin
  assignfile(f, filepath);
  reset(f, 1);

  // Read
  setlength(tempbeginarr, offset);
  setlength(tempendarr, filesize(f) - (offset + count));

  blockread(f, tempbeginarr[0], high(tempbeginarr) + 1);
  seek(f, offset + count);
  blockread(f, tempendarr[0], high(tempendarr) + 1);

  closefile(f);

  // Write
  assignfile(f, filepath);
  rewrite(f, 1);
  blockwrite(f, tempbeginarr[0], high(tempbeginarr) + 1);
  blockwrite(f, tempendarr[0], high(tempendarr) + 1);

  closefile(f);
end;

function ReadHex(filepath: string; offset: integer; count: integer): byDynamicArr;
var
  f: file;
  arr: byDynamicArr;

begin
  setlength(arr, count);
  fillchar(arr[0], count, 0);

  if FileExists(filepath) then
  begin
    assignfile(f, filepath);
    reset(f, 1);

    seek(f, offset);
    blockread(f, arr[0], count);

    closefile(f);
  end;
  Result := arr;
end;

function ReadByte(filepath: string; offset: integer): byte;
var
  f: file;
  arr: byDynamicArr;

begin
  setlength(arr, 1);
  fillchar(arr[0], 1, 0);

  if FileExists(filepath) then
  begin
    assignfile(f, filepath);
    reset(f, 1);

    seek(f, offset);
    blockread(f, arr[0], 1);

    closefile(f);
  end;
  Result := arr[0];
end;

function ReadWord(filepath: string; offset: integer): integer;
var
  f: file;
  arr: byDynamicArr;

begin
  setlength(arr, 2);
  fillchar(arr[0], 2, 0);

  if FileExists(filepath) then
  begin
    assignfile(f, filepath);
    reset(f, 1);

    seek(f, offset);
    blockread(f, arr[0], 2);

    closefile(f);
  end;
  Result := arr[1] * 256 + arr[0];
end;

function ReadInt(filepath: string; offset: integer): integer;
var
  f: file;
  arr: byDynamicArr;

begin
  setlength(arr, 4);
  fillchar(arr[0], 4, 0);

  if FileExists(filepath) then
  begin
    assignfile(f, filepath);
    reset(f, 1);

    seek(f, offset);
    blockread(f, arr[0], 4);

    closefile(f);
  end;
  Result := arr[3] * 16777216 + arr[2] * 65535 + arr[1] * 256 + arr[0];
end;

end.

역시 제가 쓰기 위해 직접 제작한 함수들입니다. 이 함수들을 사용하기 위해서는

[Delphi] Ansi String <-> Hex <-> Byte Array 함수
 이 글에 있는 pas 파일이 반드시 필요합니다.

이 글의 함수들은 저 위의 글에 함수들도 쓰고 있고 type byDynamicArr 라는 변수 타입을 쓰고 있기 때문에 꼭 있어야합니다.

uses 로 위의 글에 있는 함수가 코딩되어 있는 파일을 포함해주시면 됩니다.


파일도 함께 첨부합니다.



예제)
procedure Example();
var
  arr: byDynamicArr;
  str, Hexs: string;

begin
  str := 'Hello! Everyone. It is Example. ';
  Hexs := AnsiStrtoHex(str);

  str := 'Hey! Do you understand?';
  arr := HextoByteArr(AnsiStrtoHex(str));

  // Overload string, byDynamcArr
  PutHex('C:\e.txt', arr, 0); // t.txt -> Hey! Do you understand?
  PutHex('C:\e.txt', Hexs, 0); // t.txt -> Hello! Everyone. It is Example.

  InsertHex('C:\e.txt', arr, GetFileSize('C:\e.txt'));
  // t.txt -> Hello! Everyone. It is Example. Hey! Do you understand?

  RemoveHex('C:\e.txt', 0, length('Hello! Everyone. '));
  // t.txt -> It is Exmaple. Hey! Do you understand?

  arr := ReadHex('C:\e.txt', 0, GetFileSize('C:\e.txt'));
  str := HexTostr(arr);
  showMessage(str); //It is Example. Hey! Do you understand?
end;


ReadInt, ReadWord, ReadByte 도 설명드리겠습니다.

파일 Binary가  00000000 : 11 22 33 44 00 00 00 00 00 ... 이런 식으로 되어있다고 가정합시다.

var
  i: integer;
  by : byte;

begin
  i := ReadInt(filepath, 0); // i = 0x44332211
  i := ReadWord(filepath, 0); //i = 0x2211
  by := ReadByte(filepath, 0); //by : 0x11
end;

ReadInt 는 4Byte, ReadWord 는 2Byte, ReadByte 는 1Byte 를 읽는겁니다.