Q&A

  • readln에서 char(10) 처리 문제..


100메가 정도 되는 큰 text 파일을 한 줄씩 읽어들이려고 하는데요..



문제는 그 파일에 char(13)뿐만 아니라..



char(10)으로 line이 나뉘어져 있는게 문제입니다.. ㅠ.ㅠ



readln으로 읽어들이면 char(13)에서만 끊어버리기 때문에..



이것을 못 쓰는데요..



그래서.. read로 한 글자씩 읽었더니 시간이 너무 오래 걸리구요..



어떻게 좋은 해결책이 없을까요?





1  COMMENTS
  • Profile
    류종택 2001.04.02 08:33
    우선 100메가나 되는 텍스트 화일에다가

    13 또는 10으로 섞여서 라인처리된 것이 본인의 뜻이었다면..

    그것을 바꾸라는 쓸데없는 조언을 드리고 싶네요.

    부득히 사정이 있을 듯 한데.. 아니라면 설계를 다시 점검하실 필요는??



    여하튼 질문하신 내용은 택스트로 처리할 방도가 없는 듯 합니다.

    결국 바이너리처럼 읽어서 하나 하나 처리해주는 수 밖에요.

    한 바이트씩 읽어오는 것은 원래 퍼포먼스에 문제가 있는 방법이니.

    결국 버퍼를 통해서 한 거번에 읽어오고 처리 후 다음을 읽는 식으로 할 수 밖에 없어요. 그렇다고 해도 100메가라면 여전히 느릴 수 밖에 없지만..



    아래 예제는 제가 터보파스칼 4.0인가 5.0 때 대용량 화일 처리에 필요해서 만든 겁니다.

    컴파일은 되네요.. 하지만 예전에 무신 버그가 있었던 걸 고친 기억이 나는데..

    10년 전 일이라서 이것이 버그가 고쳐진 버젼인지는 모르겠습니다. 죄송 --;



    기능은 화일을 마치 배열처럼 사용할 수 있도록하는 것입니다.

    마치 기가 바이트 짜리 배열처럼요. 배열이 아무래도 사용이 쉽자나요.

    버퍼링을 하기 때문에 속도 저하문제는 어느 정도 해결될거고요.



    사용방법은 아래와 같습니다.

    (저도 한 참 해멨어요.. 너무 오래된 파일이라 --;)



    procedure TForm1.Button1Click(Sender: TObject);

    Var

    Ch : Char;

    Loop : Integer;

    SwapFile : SwapType;

    begin

    SwapFile.DataSize:= 1;

    SwapFile.BufferSize:= 4096;

    SwapFile.OpenBufferFile('C:Data.Dat');



    For Loop:= 1 to 10 do

    Begin

    SwapFile.DataInFile(Loop, @Ch);

    Memo1.Text:= Memo1.TextCh);

    End;



    SwapFile.CloseBufferFile;

    end;







    From 류..



    ---------



    {$I-}

    Unit Swap;



    Interface



    Type

    BufferType = Packed Array [1..$FFFF] of Byte;

    SwapType = Object

    Private

    BufferFile : File;

    Pos, RRead : Integer;

    Buffer : ^BufferType;

    Public

    BufferSize, DataSize, ListSize, FSize : Integer;

    Procedure OpenBufferFile(FileName:String);

    Function ByteInFile(Index:Integer):Byte;

    Procedure DataInFile(Index:Integer; Data:Pointer);

    Procedure CloseBufferFile;

    End;

    Var

    SwapError : Byte;



    Implementation



    Procedure SwapType.OpenBufferFile(FileName:String);

    Begin

    AssignFile(BufferFile, FileName);

    Reset(BufferFile, 1);

    If IOResult <> 0 then

    Begin

    SwapError:= IOResult;

    Pos:= 1;

    FSize:= 0;

    ListSize:= 0;

    End

    Else

    Begin

    SwapError:= 0;

    GetMem(Buffer, BufferSize+DataSize);

    Pos:= 1;

    FSize:= FileSize(BufferFile);

    ListSize:= FSize Div DataSize;

    If FSize >= BufferSize+DataSize then

    BlockRead(BufferFile, Buffer^, BufferSize+DataSize, RRead)

    Else

    BlockRead(BufferFile, Buffer^, FSize, RRead);

    End;

    End;



    Function SwapType.ByteInFile(Index:LongInt):Byte;

    Var

    Temp : Integer;

    Begin

    Result:= 0;

    If FSize = 0 then Exit;

    Temp:= ((Index-1) Div BufferSize) + 1;

    If Temp <> Pos then

    Begin

    Pos:= Temp;

    Temp:= FSize - (Pos-1)*BufferSize;

    Seek(BufferFile, (Pos-1)*BufferSize);

    If Temp >= BufferSize then

    BlockRead(BufferFile, Buffer^, BufferSize, RRead)

    Else

    BlockRead(BufferFile, Buffer^, Temp, RRead);

    End;

    Temp:= Index - (Pos-1)*BufferSize;

    ByteInFile:= Buffer^[Temp];

    End;



    Procedure SwapType.DataInFile(Index:LongInt; Data:Pointer);

    Var

    Temp : Integer;

    Begin

    If FSize = 0 then Exit;

    Temp:= (((Index-1)*DataSize) Div BufferSize) + 1;

    If Temp <> Pos then

    Begin

    Pos:= Temp;

    Temp:= FSize - (Pos-1)*BufferSize;

    Seek(BufferFile, (Pos-1)*BufferSize);

    If Temp >= BufferSize+DataSize then

    BlockRead(BufferFile, Buffer^, BufferSize+DataSize, RRead)

    Else

    BlockRead(BufferFile, Buffer^, Temp, RRead);

    End;

    Temp:= Index - ((Pos-1)*(BufferSize Div DataSize));

    Move(Buffer^[(Temp-1)*DataSize+1], Data^, DataSize);

    End;



    Procedure SwapType.CloseBufferFile;

    Begin

    If FSize = 0 then Exit;

    CloseFile(BufferFile);

    FreeMem(Buffer, BufferSize+DataSize);

    End;



    End.





    초보 wrote:

    >

    > 100메가 정도 되는 큰 text 파일을 한 줄씩 읽어들이려고 하는데요..

    >

    > 문제는 그 파일에 char(13)뿐만 아니라..

    >

    > char(10)으로 line이 나뉘어져 있는게 문제입니다.. ㅠ.ㅠ

    >

    > readln으로 읽어들이면 char(13)에서만 끊어버리기 때문에..

    >

    > 이것을 못 쓰는데요..

    >

    > 그래서.. read로 한 글자씩 읽었더니 시간이 너무 오래 걸리구요..

    >

    > 어떻게 좋은 해결책이 없을까요?

    >

    >