2013-05-31

[델파이]파일 읽기 쓰기


unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Gauges;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Button4: TButton;
    ProgressBar1: TProgressBar;
    Gauge1: TGauge;
    Animate1: TAnimate;
    Button3: TButton;
    Button5: TButton;
    Button6: TButton;
    procedure Button6Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
//------------------------------------------------------------------------------
// 파일생성
//------------------------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
  F : TextFile;
  FH : Integer;
begin
  // AssignFile로 파일 생성  AssignFile(F, 'C:\DelphiSourceDataRoom\파일다루기\AssignFile.txt');
  Rewrite(F); // 쓰기모드로 오픈
  CloseFile(F); // 파일 닫음
  // FileCreate로 파일 생성
  FH := FileCreate('C:\DelphiSourceDataRoom\파일다루기\FileCreate.txt');
  FileClose(FH); // 파일닫음
end;
//------------------------------------------------------------------------------
// 파일 읽고 쓰고 복사하기
//------------------------------------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
var
  FH1, FH2 : Integer; // 파일 핸들  Buffer : array[1..1024] of char; // 버퍼  iCount : Integer; // 파일크기  iFileSize : Integer; // 파일크기
begin
  if OpenDialog1.Execute then begin // 열기 대화상자 실행    // fmShareDenyWrite : 다른파일을 사용하고있어도 읽어올수있도록 허용    FH1 := FileOpen(OpenDialog1.FileName, fmShareDenyWrite); // 파일 오픈    iFileSize := FileSeek(FH1, 0, 2); // 파일 사이즈 측정(주의. 파일끝으로 포인터이동)    FileSeek(FH1, 0, 0); // (파일 포인터를 맨앞으로 다시이동)
    if FH1 <> -1 then begin // FH1 파일 핸들값이 존재한다면
      if SaveDialog1.Execute then begin // 저장 대화상자 실행        FH2 := FileCreate(SaveDialog1.FileName); // 저장명으로 파일생성
          if FH2 <> -1 then begin // 생성한 FH2 파일행들값이 존재한다면
            // 파일을 1024만큼 읽어드리고 그 크기를 반환한다.
            iCount := FileRead(FH1, Buffer, sizeof(Buffer));
            // 프로그레스바 초기화
            ProgressBar1.Min := 0;
            ProgressBar1.Max := iFileSize;
            ProgressBar1.Position := 0;
            // 게이지 초기화            Gauge1.MinValue := 0;
            Gauge1.MaxValue := iFileSize;
            Gauge1.Progress := 0;
            // 에니메이터 초기화
            Animate1.CommonAVI := aviCopyFiles;
            while iCount <> 0 do begin // 파일에 내용이 있을때까지 반복해서 읽는다.
              ProgressBar1.Position := ProgressBar1.Position + sizeof(Buffer); // 진행상태 프레그레스바에 표시              Gauge1.Progress := Gauge1.Progress + sizeof(Buffer); // 진행상태 게이지에 표시
              FileWrite(FH2, Buffer, iCount); // FH1의 내용을 FH2에 쓴다              iCount := FileRead(FH1, Buffer, sizeof(Buffer)); // FH1 뒤에 이어서 읽어들인다.            end;
            // 에니메이터 동작 중지            Animate1.Active := False;
            Animate1.Visible := False;
            ShowMessage('파일 복사작업이 완료되었습니다.');
          End
          else begin
            ShowMessage('파일을 생성하던중 에러가 났습니다.');
            FileClose(FH1); // FH1 파일을 닫는다.          End;
      End;
      FileClose(FH2); // FH2 파일을 닫는다.    End
    else ShowMessage('파일 오픈시 에러가 발생하였습니다.');
    FileClose(FH1); // FH1를 닫는다.  End;
End;
//------------------------------------------------------------------------------
// 파일 크기 알아보기
//------------------------------------------------------------------------------

procedure TForm1.Button4Click(Sender: TObject);
var
  FH3 : Integer;
  iFileSize : Integer;
begin
  FH3 := FileOpen('C:\DelphiSourceDataRoom\파일다루기\AssignFile.txt', fmShareDenyWrite);
  // FileSeek Origin(Handle, Offset, Origin)
  // 0 : 파일 포인터가 파일의 처음에서 Offset의 바이트수에 해당하는 위치로 포인터를 이동.
  // 1 : 파일 포인터가 현재의 위치에서 Offset의 바이트수에 해당되는 위치로 포인터를 이동.
  // 2 : 파일 포인터가 파일의 끝에서 Offset의 바이트수에 해당되는 위치로 포인터를 이동
  iFileSize := FileSeek(FH3, 0, 2); // 파일 사이즈  ShowMessage('AssignFile.txt : ' + IntToStr(iFileSize));
  FileClose(FH3); // 파일 닫기end;
// 파일의 생성 날짜 조회
procedure TForm1.Button3Click(Sender: TObject);
var
  dtDate : TDateTime; // 파일 생성날짜  FH4 : Integer; // 파일핸들
begin
  if OpenDialog1.Execute then begin // 열기 대화상자 실행    // fmShareDenyWrite : 다른파일을 사용하고있어도 읽어올수있도록 허용
    FH4 := FileOpen(OpenDialog1.FileName, fmShareDenyWrite); // 파일 오픈    dtDate := FileDateToDateTime(FileGetDate(FH4)); // 파일의 날짜 조회    ShowMessage(DateTimeToStr(dtDate));
    FileClose(FH4); // 파일 닫음  end;
end;
//------------------------------------------------------------------------------
// 디렉토리내에서 파일찾기
//------------------------------------------------------------------------------

procedure TForm1.Button5Click(Sender: TObject);
var
  Form2 : TForm2;
begin
  Form2 := TForm2.Create(Application);
  Form2.Show;
end;
//------------------------------------------------------------------------------
// 파일의 속성값 얻어오고 변경하기
//------------------------------------------------------------------------------

procedure TForm1.Button6Click(Sender: TObject);
var
  FH5 : Integer;
  FileSetDataResult: Integer;
  FileDate: Integer;
begin
  if OpenDialog1.Execute then begin // 열기 대화상자 실행
    // 파일을 읽기속성 or 쓰기 속성으로 바꿈    FileSetAttr(OpenDialog1.FileName, fmShareDenyNone);
    FH5 := FileOpen(OpenDialog1.FileName, fmOpenReadWrite); // 파일 오픈
    try
      // 파일날짜 변경
      FileDate := DateTimeToFileDate(StrToDateTime('2001-05-21 01:01:01'));
      FileSetDataResult := FileSetDate(FH5, FileDate);
      if FileSetDataResult <> 0 then
      begin
        ShowMessage('파일날짜 변경 실패 : '+IntToStr(FileSetDataResult));
      end;
    finally
      FileClose(FH5); // 파일 닫음    end;
    // FileSetAttr(OpenDialog1.FileName, faReadOnly); // 파일을 읽기속성으로 바꿈  End;
end;
end.

[델파이] stored procedure 사용하기

파이로 C/S 프로그램밍을 하다 보면, SQL 서버의 성능 및 보안 등 여러 유용함으로 저장 프로시저를 많이 사용하게 됩니다. 아래는 ADO의 TADOStoredProc를 통한 저장 프로시저 호출에 대한 부분을 정리하여 보았습니다. ADO가 아닌 다른 경우에도 대동소이할겁니다.

1. 호출 과정
  1. TADOStoredProc 객체를 생성(Create)합니다.
  2. 저장 프로시저를 호출하기 위한 여러 속성들, 연결(Connection) 및 저장 프로시저 이름(ProcedureName) 등을 설정합니다.
  3. 파라미터를 초기화합니다.(CreateParameter)
  4. 저장 프로시저를 실행합니다.(Open / ExecProc)
  5. 저장 프로시저가 실행된 결과를 받아서 처리합니다.(RecordCount, Eof, Fields, MoveNext 등)
  6. 사용이 끝난 객체는 닫고 소멸시킨다.


2. Open(또는 Active)과 ExecProc의 차이점
  • Open(또는 Active)
    • 저장 프로시저를 실행한 결과셋을 받습니다.
    • Active 속성이 True로 설정됩니다.
    • RecordSet 속성에 결과셋이 있습니다.
  • ExecProc
    • 저장 프로시저를 서버에서 실행만 시킵니다.
    • Active, RecordSet 속성이 변화하지 않습니다.

3. 저장 프로시저의 RETURN 값 받아 처리하기
  • 파라미터를 추가할 때, 제일 먼저 "@RETURN_VALUE" 파라미터를 추가합니다.
  • 저장 프로시저가 실행되고 난 후의 결과를 파리미터로 받아옵니다.

01.var
02.ADOStoredProc1 : TADOStoredProc;
03.begin
04.ADOStoredProc1 : TADOStoredProc.Create(nil);
05.with ADOStoredProc1 do
06.try
07.ProcedureName := 'usp_stored_proc';
08.Connection := FADOConnection;
09.Parameters.Clear;
10.Parameters.CreateParameter('RETURN_VALUE', ftInteger, pdReturnValue, 0, null);
11.Parameters.CreateParameter('@start_temp_no', ftInteger, pdInput, 0680000);
12. 
13.ExecProc;
14.ShowMessage('RETURN_VALUE = ' + IntToStr(Parameters[0].Value) + #13#10 +
15.'RecordCount = ' + IntToStr(Recordset.RecordCount));
16. 
17.// Error 발생
18.finally
19.ADOStoredProc1.Free;
20.end;
21.end;

  • 위 예제에서는 마지막 라인에서 오류가 발생합니다. 왜냐하면 ExecProc는 결과셋을 받지 않기 때문에, RecordCount 속성을 접근하려할 때 오류가 발생하게 된다.
  • 위와 같이 저장 프로시저의 파라미터를 직접 생성하여 호출할 경우에 있어서 대상 DB가 MS-SQL 서버의 경우 저장 프로시저의 파라미터를 실제 서버의 저장 프로시저 순서대로 생성(CreateParaameter)해 주어야 정상적으로 저장 프로시저가 호출이 됩니다. 그렇지 않은 경우, 전혀 엉뚱한 결과가 나오거나, 알 수 없는 오류가 발생하게 됩니다.