C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[22980] Re:[소스] 파일입출력으로다 한번 해보심이...
나그네 [] 1547 읽음    2002-12-03 10:49
아래는 파일 입출력 클래스 간단히 라인단위로 읽어 올수 있도록 만들어본
랩퍼 클래스

//선언부
class TLineFile
{
private:
  THandle lffile;
public:
  TLineFile();
  ~TLineFile();
  int FileOpen(const AnsiString FileName, unsigned Mode);
  int Open(const AnsiString FileName, unsigned Mode);
  int FileRead(void *Buffer, unsigned Count);
  int Read(void *Buffer, unsigned Count);
  int FileWrite(const void *Buffer, unsigned Count);
  int Write(const void *Buffer, unsigned Count);
  int FileReadLn(void *Buffer, unsigned Count);
  int ReadLn(void *Buffer, unsigned Count);
  int FileSeek(int Offset, int Origin);
  int Seek(int Offset, int Origin);
  bool FEof();
  void FileClose();
  void Close();
};

//정의부
TLineFile::TLineFile()
{
  this->lffile  = 0;
}

TLineFile::~TLineFile()
{
  if(this->lffile != 0) {
    this->FileClose();
  }
}

int TLineFile::FileOpen(const AnsiString FileName, unsigned Mode)
{
  lffile = ::FileOpen(FileName, Mode);
  return lffile;
}

int TLineFile::Open(const AnsiString FileName, unsigned Mode)
{
  return this->FileOpen(FileName, Mode);
}

int TLineFile::FileRead(void *Buffer, unsigned Count)
{
  ::ZeroMemory(Buffer, Count);
  return ::FileRead(this->lffile, Buffer, Count);
}

int TLineFile::Read(void *Buffer, unsigned Count)
{
  ::ZeroMemory(Buffer, Count);
  return this->FileRead(Buffer, Count);
}

int TLineFile::FileWrite(const void *Buffer, unsigned Count)
{
  return ::FileWrite(this->lffile, Buffer, Count);
}

int TLineFile::Write(const void *Buffer, unsigned Count)
{
  return this->FileWrite(Buffer, Count);
}

int TLineFile::FileReadLn(void *Buffer, unsigned Count)
{
  int oseek = this->FileSeek(0, 1);
  int ret   = this->FileRead(Buffer, Count);
  char * cpos = StrPos((char*)Buffer, "\r\n");
  if(cpos != NULL) {
    ret = cpos-(char*)Buffer;
    this->FileSeek(oseek+ret+2, 0);
    ::ZeroMemory(cpos, Count-ret);
  }
  return  ret;
}

int TLineFile::ReadLn(void *Buffer, unsigned Count)
{
  return FileReadLn(Buffer, Count);
}

int TLineFile::FileSeek(int Offset, int Origin)
{
  return ::FileSeek(this->lffile, Offset, Origin);
}

int TLineFile::Seek(int Offset, int Origin)
{
  return this->FileSeek(Offset, Origin);
}

bool TLineFile::FEof()
{
  int cp = this->FileSeek(0, 1);
  int ceof = this->FileSeek(0, 2);
  this->FileSeek(cp, 0);
  return (cp >= ceof);
}

void TLineFile::FileClose()
{
  ::FileClose(this->lffile);
  this->lffile = 0;
}

void TLineFile::Close()
{
  this->FileClose();
}

// 여기가 끝             

// 사용법
// 90000만건 정도가 1.5초 정도
// 라인단위로 읽는 방법은 블럭 단위로 읽어서
// 개행문자를 추출한 후 그 위치 + 2 가 다음 파일 위치고
// 뒷문자는 클리어 하는 방식임

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int count;
  char Buffer[151];
  AnsiString  fname = ExtractFilePath(Application->ExeName) + "linefile.txt";

  TLineFile *lfile  = new TLineFile();
  lfile->FileOpen(fname, fmOpenRead);
  int nFirst = GetTickCount();
  while(true) {
    if(lfile->FEof()) break;
    lfile->FileReadLn(Buffer, 150);
  }
  Caption = IntToStr(GetTickCount()-nFirst);
  lfile->~TLineFile();
}

태즈 님이 쓰신 글 :
:  10000 * 5 = 5만라인 정도의 내용을 가지는 텍스트를 읽어서 데이타를 뽑으려 합니다.
:  각라인에는 7개의 float 변수값이 표시되어있습니다.
:
:  이걸 RichEdit 로 읽어온뒤에,
:  for( n = 0 ; n < max ; n ++ ) {
:    sscanf( RichEdit1->Lines->Strings[ n ].c_str(), " %f %f %f %f %f %f %f ", &x, &y, &z, &r, &g, &b, &a ) ;
:   
:    //-- 읽어온 데이터들 처리루틴..
:    ~~~
:    ~~~
:  }
:
:  이러한 방식으로 7개 변수값을 추출하고 있습니다.
:  6만라인을 처리하는데 생각보다 너무 많은 시간이 걸리네요.
:  요부분을 빼고 연산하는 부분만 6만번 돌리는 데는 시간이 별로 안 걸리더군요.
:  그래서 '아마도' 이 부분에서 시간을 많이 잡아먹는 것 같은데..

:  이걸 빠르게 구현하려면 어떻게 해야할까요..
:
:  ---------------------------------------
:
:  추가적으로 몇가지 테스트를 해보았습니다.
:  테스트할 파일의 길이를 달리하여 테스트한 것입니다.
:  라인수 증가에 따라서 걸리는 시간이 일차적으로 비례하지 않고 있네요.
:  테스트 벡터의 내용은 거의 비슷하기에, 연산량의 차이는 없다고 보고요.
:
:  5000 라인 :  1초미만
:  10000 라인 : 1.5초정도.
:  20000 라인 : 10초정도.
:  30000 라인 : 23초정도
:  40000 라인 : 41초정도.

:  60000 라인 : 110초.

:  어찌해야할까요...
:  --------------------------------------------
:
:  여전한 극초보 태즈였습니다.
:  감사합니다.

+ -

관련 글 리스트
22958 [질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 태즈 899 2002/12/02
31286     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 김상구.패패루 995 2002/12/02
31285     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 김상구.패패루 1035 2002/12/02
31284     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 태즈 909 2002/12/02
31283     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 태즈 999 2002/12/02
31282     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 김백일.cedar 922 2002/12/02
31281     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 김백일.cedar 972 2002/12/02
22987     Re:[감사] 우선 FILE, fread, fwrite 등으로 해결했습니다. 태즈 2109 2002/12/03
22980     Re:[소스] 파일입출력으로다 한번 해보심이... 나그네 1547 2002/12/03
22967     Re:[질문] 6만라인 파일 빨리 읽고, 각 라인을 scanf하기. 나그네 1057 2002/12/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.