было любопытно, поэтому я протестировал TRichEdit
и придумал следующее:
//---------------------------------------------------------------------------
void load_text(TRichEdit *re,AnsiString filename,TProgressBar *pb)
{
// variables
int hnd,adr,siz,len,i;
const int _buf=128*1024; // buffer size
AnsiString s,s0;
char buf[_buf+1];
// open file and detect size
hnd=FileOpen(filename,fmOpenRead); if (hnd<0) return;
siz=FileSeek(hnd,0,2);
FileSeek(hnd,0,0);
// prepare progress bar
pb->Position=0;
pb->Max=siz;
pb->Visible=true;
// process txt file by chunks
for (s0="",adr=0;adr<siz;)
{
// update progress bar and GUI
pb->Position=adr;
Application->ProcessMessages();
// load chunk
len=FileRead(hnd,buf,_buf);
adr+=len; buf[len]=0;
// handle cutted lines by chunk size
s=s0; s0="";
// ignore last 2 lines for chunks (except last chunk)
if (len==_buf)
{
// skip last line
for (i=len-1;i>=0;i--)
if ((buf[i]==13)||(buf[i]==10))
{
i--;
if (i>=0)
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
break;
}
// skip another line to avoid inserting empty line if eol is cutted
for (;i>=0;i--)
if ((buf[i]==13)||(buf[i]==10))
{
s0+=buf+i+1; // copy last 2 lines into s0
i--;
if (i>=0)
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
i++; if (i<0) i=0; buf[i]=0; // end of string
break;
}
}
// last chunk ignore last eol
else{
// skip last line
i=len-1;
if ((buf[i]==13)||(buf[i]==10)) // eol code
{
i--;
if (buf[i]!=buf[i+1]) // different eol code to ignore empty line
if ((buf[i]==13)||(buf[i]==10)) // eol code
i--;
i++; if (i<0) i=0; buf[i]=0; // end of string
}
}
// add actual chunk
s+=buf;
re->Lines->Add(s);
}
// tidy up
pb->Visible=false;
FileClose(hnd); hnd=-1;
}
//---------------------------------------------------------------------------
Похоже, это работает без описанной вами конечной паузы, которая может быть связана с версией IDE / VCL / compiler Я использую BDS2006 Turbo C ++ . При тестировании на ~ 23 МБайт STL-файле время загрузки составляет ~ 10 с c (TMemo
занимает вдвое больше, чем бог знает почему) ...
Сохраненный файл (в то время как PlainText=true
) идентичен загруженный, поэтому код должен быть правильным.
Здесь анимированный GIF предварительного просмотра:
при использовании так:
void __fastcall TForm1::FormActivate(TObject *Sender)
{
//tbeg();
load_text(re_txt,"in.txt",pb_progress);
//tend();
//Caption=tstr();
re_txt->Lines->SaveToFile("out.txt");
}
, где pb_progress
- это TProgressBar
, а re_txt
- это TRichEdit
.
Как видите, обратный вызов не требуется ...
PS. Если вы хотите измерить время, как я (закомментированные строки), здесь представлены реализации tbeg/tend/tstr
функций: