Q&A

  • 바이너리 파일의 특정 위치의 데이터 바꾸기

바이너리 파일을 읽어서 특정위치의 1 바이트를 다른 값으로 변경하여
저장하고자 합니다.

델파이 도움말에 있는 예제에 있는 것처럼 기존의 파일을 읽어서 새로운
파일로 복사하면서 해당 위치의 값을 변경하여 저장하는 식으로 하니까
시간이 많이 걸리는군요.

그냥 원본파일을 읽어서 해당위치로 이동(FileSeek 나 Seek)하여 한 바이트의
값을 변경한 후, 바로 저장할 수 있는 방법은 없는지요.
참고로 바이너리 파일의 크기는 수백메가 정도 됩니다.

var
  FromF, ToF: file;
  NumRead, NumWritten: Integer;
  Buf: array[1..2048] of Char;
begin
  if OpenDialog1.Execute then     { Display Open dialog box }
  begin
    AssignFile(FromF, OpenDialog1.FileName);
    Reset(FromF, 1);        { Record size = 1 }
    if SaveDialog1.Execute then      { Display Save dialog box}
    begin
      AssignFile(ToF, SaveDialog1.FileName);        { Open output file }

      Rewrite(ToF, 1);        { Record size = 1 }
      Canvas.TextOut(10, 10, 'Copying ' + IntToStr(FileSize(FromF))
        + ' bytes...');
      repeat
        BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
        BlockWrite(ToF, Buf, NumRead, NumWritten);
      until (NumRead = 0) or (NumWritten <> NumRead);
      CloseFile(FromF);
      CloseFile(ToF);
    end;
  end;
end;
2  COMMENTS
  • Profile
    박서규 2003.01.26 12:35
    흠... 저라면..  TFileStream을 쓰겠어여... 물론 더 좋은 방법이

    있을 수 있지만,,,

    델의 파일스트림은 스트림에서 받은것이고 쓰는 방법또한 간단하므로

    님께서 하시는 작업의 유형과 딱 맞을 것 같군요..

    일단 TFileStream을 생성할때 화일 이름과 여는 모드를 설정한 다음..

    포지션을 특정한 곳으로 옮긴다음 해당 스트림에 Write를 하면 됩니다.

    간단하져..??

    복사를 하지 않고도 쉽게 바꿀 수 있을 것 같군요...


  • Profile
    심재용 2003.01.26 12:00
    // 첫번째 방법은 파일스트림을 이용한 방법입니다.
    // 바이너리 파일일 경우 확인방법은 울트라 에디트등으로 확인하시면
    // 될 것 같습니다.
    procedure TForm1.Button1Click(Sender: TObject);
    var
      nFileStream : TFileStream;
      nBuf: char;
    begin
      OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);
      if OpenDialog1.Execute then begin   { Display Open dialog box }
        nFileStream := TFileStream.Create(OpenDialog1.FileName,fmOpenReadWrite);
        nBuf := 'x';
        try
          nFileStream.Position := 18;
          nFileStream.Write(nBuf,SizeOf(nBuf));
        finally
          nFileStream.Free ;
        end;
      end;
    end;

    // 두번째 방법은 그냥 BlockWrite 를 이용한 방법입니다.
    procedure TForm1.Button1Click(Sender: TObject);
    var
      nFile: file;
      nBuf: Char;
    begin
      OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);
      if OpenDialog1.Execute then begin    { Display Open dialog box }
        AssignFile(nFile, OpenDialog1.FileName);
        Reset(nFile, 1);    { Record size = 1 }
        Seek(nFile,16); {파일의 처음부터 16Byet 이동}
        nBuf := 'A';
        BlockWrite(nFile,nBuf,SizeOf(nBuf));
        CloseFile(nFile);
      end;
    end;