StartprogrammingusingObjectPascal:CopyFilesUsingUntypedFilesProgram

From 흡혈양파의 번역工房
Revision as of 10:00, 26 July 2012 by Onionmixer (talk | contribs) (SPOP 비형식화된파일을사용하는파일복사프로그램 페이지 추가)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

비형식화 된 파일을 사용하는 파일 복사 프로그램

Program FilesCopy2;

{$mode objfpc}{$H+}

uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Classes, SysUtils
    { you can add units after this };

var
    SourceName, DestName: string;
    SourceF, DestF: file;
    Block: array [0 .. 1023] of Byte;
    NumRead: Integer;
begin
    Writeln('Files copy');
    Write('Input source file name: ');
    Readln(SourceName);
    Write('Input destination file name: ');
    Readln(DestName);

    if FileExists(SourceName) then
    begin
        AssignFile(SourceF, SourceName);
        AssignFile(DestF, DestName);

        FileMode:= 0;          // open for read only
        Reset(SourceF, 1); // open source file
        Rewrite(DestF, 1); // Create destination file

        // Start copy
        Writeln('Copying..');
        while not Eof(SourceF) do
        begin
            // Read Byte from source file
            BlockRead(SourceF, Block, SizeOf(Block), NumRead);
            // Write this byte into new destination file
            BlockWrite(DestF, Block, NumRead);
        end;
        CloseFile(SourceF);
        CloseFile(DestF);
    end
    else // Source File not found
        Writeln('Source File does not exist');

    Write('Copy file is finished, press enter key to close..');
    Readln;
end.

앞의 예제에서 새로운 것은

1. 파일의 선언 형식

SourceF, DestF: file;


2. 읽기/쓰기 변수 (Buffer)

Block: array [0 .. 1023] of Byte;

파일의 블록을 읽고 복사하기 위해 (1킬로바이트의 수정할 수 있는)바이트 배열을 사용했습니다.


3. 추가 인자를 필요로 하는 비형식화된 파일 열기

        Reset(SourceF, 1); // open source file
        Rewrite(DestF, 1); // Create destination file

추가 인자는 한 번에 읽고 쓸 수 있는 가장 작은 요소인 레코드의 크기 입니다. 임의의 파일 형식을 복사하려 할 때 1 바이트가 될 수도 있다는 의미인데, 임의의 파일 사이즈에 대해 사용할 수 있기 때문입니다.


4. Read 프로시저

    BlockRead(SourceF, Block, SizeOf(Block), NumRead);

BlockRead 프로시저는 비형식화 된 파일에 사용합니다. 한 번에 많은 양의 데이터를 읽습니다.

BlockRead 프로시저의 인자는 다음과 같습니다.

  • SourceF : 복사하려는 원본 파일 변수입니다.
  • Block : 읽고 쓸 현재 데이터를 저장할 변수나 배열입니다.
  • SizeOf(Block) : 한번에 읽을 레코드의 수를 결정한 값입니다. 예를 들어 100을 입력했다면, 100 개의 레코드(이 경우의 단위는 바이트입니다)를 읽으려 한다는 의미입니다. SizeOf 함수를 사용한다면, 보통 컨테이너(바이트 배열)의 수만큼 레코드를 읽으려 한다는 의미입니다.
  • NumRead : 정해진 레코드 수(1024) 만큼 읽어 들이라고 BlockRead 함수에 알렸지만, 때로는 모든 레코드 수만큼 읽어들이기도 하지만, 일부만 읽어들이기도 합니다. 예를 들어 100 바이트만 들어있는 파일을 읽어들이려 한다면, BlockRead는 100바이트만 읽을 수 있다는 뜻입니다. 또한 정해진 양보다 적은 레코드를 읽어들이는 것은 파일의 마지막 블록에서도 일어날 수 있습니다. 예를 들어, 만약 1034 바이트가 들어있는 파일을 읽어들인다면, 처음 순환 과정에서는 1024 바이트를 읽어들이겠지만, 그 다음 순환 과정에서는 남은 10바이트만 읽어들일 것이고 Eof 함수는 True를 되돌릴 것입니다. BlockWrite 프로시저와 함께 사용하려면 NumRead 값이 필요합니다.


5. 비형식화 된 파일에 기록

BlockWrite(DestF, Block, NumRead);

쓰기 프로시저이며, BlockRead 프로시저와 유사하지만, 몇 가지 차이점이 있습니다.

  1. SizeOf 프로시저를 사용하는 대신에 NumRead를 사용했는데, NumRead에 실제 읽어들인 블록 크기가 들어있기 때문입니다
  2. 네번째 인자인 NumWritten(여기 예제에는 없습니다)은 중요하지 않은데, 디스크가 가득 차기 전까지는 우리가 정한 대로 항상 기록한 레코드를 가져오기 때문입니다.

이 프로그램을 실행한 후, 큰 파일을 복사하는 속도에 주목해봅니다. 파일에 1메가바이트가 들어있다면, 전체 파일을 복사하는데 읽기/쓰기에 필요한 횟수가 대략 천 번 정도밖에 되지 않습니다.

다음 예제에서는 임의의 파일을 읽기 위해 비형식화 된 파일을 사용할 것이며, 메모리나 디스크에 저장한 내용을 보여줄 것입니다. 아시는 바와 같이, 파일은 바이트의 목록입니다.