Текущий архив: 2003.02.17;
Скачать: CL | DM;
ВнизОткрытие большого файла Найти похожие ветки
← →
Sherbacov (2003-02-06 23:22) [0]Уважаемые мастера, помогите в решении проблемы
существует большой тестовой файл 300 мегов, я открываю его (я знаю это не правильно)memo1.lines.loadfromfile("big.txt");
и перехожу на строчку последнюю минус 9.
Но очень долго и еще файлы да 150 мегов открывает нормально, а больше с ошибкой.
Помогите.
← →
Palladin (2003-02-06 23:39) [1]а ты хотел что бы у тебя 300 мегов за 2 секунды перелопатилось...
ничесе запросы...
← →
Sherbacov (2003-02-06 23:42) [2]Но, файлы начиная с 200 мегов, вообще не работает
← →
MBo (2003-02-06 23:43) [3]
procedure TForm1.Button1Click(Sender: TObject);
var fs:TFileStream;
buf:array[0..4095] of char;
NStr,i,j,BufSize,OldPos:integer;
s:string;
begin
NStr:=9;
fs:=TFileStream.Create("e:\unit1.pas",fmOpenRead or fmShareDenyNone);
BufSize:=4096;
if fs.Size<BufSize then
BufSize:=fs.Size;
fs.Seek(-BufSize,soFromEnd);
fs.Read(buf,bufsize);
if buf[bufsize-1]=#10 then
OldPos:=BufSize-1
else
OldPos:=BufSize+1;
j:=0;
for i:=bufsize-2 downto 0 do begin
if buf[i]=#10 then begin
SetLength(s,OldPos-i-2);
Move(buf[i+1],s[1],OldPos-i-2);
OldPos:=i;
Memo1.Lines.Add(s);
inc(j);
if j=NStr then Break;
end;
end;
fs.Free;
end;
← →
Palladin (2003-02-06 23:44) [4]хоть бы текст сообщения об ошибке сюда кинул.
может у тебя там EOutOfMemory :))
← →
Sherbacov (2003-02-06 23:46) [5]Спасибо, вот это я и искал.
← →
Palladin (2003-02-06 23:52) [6]2 MBo
а чем собственно говоря это отличается от
procedure TStrings.LoadFromStream(Stream: TStream);
var
Size: Integer;
S: string;
begin
BeginUpdate;
try
Size := Stream.Size - Stream.Position;
SetString(S, nil, Size);
Stream.Read(Pointer(S)^, Size);
SetTextStr(S);
finally
EndUpdate;
end;
end;
procedure TStrings.SetTextStr(const Value: string);
var
P, Start: PChar;
S: string;
begin
BeginUpdate;
try
Clear;
P := Pointer(Value);
if P <> nil then
while P^ <> #0 do
begin
Start := P;
while not (P^ in [#0, #10, #13]) do Inc(P);
SetString(S, Start, P - Start);
Add(S);
if P^ = #13 then Inc(P);
if P^ = #10 then Inc(P);
end;
finally
EndUpdate;
end;
end;
← →
MBo (2003-02-07 00:51) [7]>Palladin
>а чем собственно говоря это отличается от
Ну сам подумай.
← →
Palladin (2003-02-07 01:02) [8]сорри...
не доконца разобрал, что именно делает процедура, но вот если произойдет ситуация если сумма 9 последних строк будет больше чем 4096 и если вдруг не 9 строку надо...
ненадежно, однако :)
← →
MBo (2003-02-07 01:11) [9]>и если вдруг не 9 строку надо...
С этим, думаю, понятно
>больше чем 4096
Надо закладывать некие разумные предположения, можно устанавливать размер буфера в зависимости от количества нужных строк, а если в нем оказалось мало строк, прочитать еще кусок
← →
Sherbacov (2003-02-07 15:15) [10]Спасибо, все работает.
← →
Игорь Шевченко (2003-02-07 15:31) [11]MMF в данном случае лучше...
← →
MBo (2003-02-07 16:10) [12]>Игорь Шевченко
Вы хочете MMF-ов? Их есть у меня ;)
procedure GetLastLines(const nstr:Integer;const FileName:string;Lines:TStrings);
var
FileH: THandle;
MapH: THandle;
Size,Count: Integer;
PMap,PB: PByte;
begin
Assert(FileExists(FileName),"File not found!");
Assert(Assigned(Lines),"Where should I write to????");
FileH:=FileOpen(FileName, fmOpenReadWrite);
if FileH<>INVALID_HANDLE_VALUE then begin
Size:=GetFileSize(FileH, nil);
MapH:=CreateFileMapping(FileH,nil,PAGE_READONLY,0,Size,nil);
if MapH<>0 then begin
PMap:=MapViewOfFile(MapH,FILE_MAP_READ,0,0,Size);
if PMap<>Nil then begin
PB:=PMap;
inc(PB, Size);
if PB^<>10 then
Count:=1
else
Count:=0;
repeat
Dec(PB);
if PB^=10 then
Inc(Count);
until (Count>nstr) or (PB=PMAP);
if PB<>PMap then
Inc(PB);
Lines.Text:=PChar(PB);
UnmapViewOfFile(PMap);
end;
CloseHandle(MapH);
end;
CloseHandle(FileH);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
GetLastLines(5,"e:\uploads.txt",Memo1.Lines);
end;
← →
Song (2003-02-07 16:19) [13]MBo, где же ты был раньше? -))
Чего-то только я не понял, а что означает параметр 5 ?
← →
Palladin (2003-02-07 16:25) [14]ну все :)
больше никогда не буду придиратся к MBo :))
а кстати почему (С), а не "M". Не порядок :)
← →
Palladin (2003-02-07 16:27) [15]2 Song
это номер нужной строки, с конца...
← →
MBo (2003-02-07 16:30) [16]5 последних строк. Надо было аргумент назвать попонятнее ;(
← →
Игорь Шевченко (2003-02-07 16:31) [17]MBo © (07.02.03 16:10)
Уважометр, однако, зашкаливает :-)
← →
MBo (2003-02-07 16:40) [18]>Игорь Шевченко
Не юродствуйте, Штирлиц ;)
Покритиковал бы лучше.
← →
MBo (2003-02-07 16:57) [19]Вариант для чтения единственной строки:
function GetNthLineFromEnd(const NumFromEnd:Integer;const FileName:string):string;
var
FileH: THandle;
MapH: THandle;
Size,Count: Integer;
PMap,PB: PByte;
PEnd:PChar;
begin
Assert(FileExists(FileName),"File not found!");
FileH:=FileOpen(FileName, fmOpenReadWrite);
if FileH<>INVALID_HANDLE_VALUE then begin
Size:=GetFileSize(FileH, nil);
MapH:=CreateFileMapping(FileH,nil,PAGE_READONLY,0,Size,nil);
if MapH<>0 then begin
PMap:=MapViewOfFile(MapH,FILE_MAP_READ,0,0,Size);
if PMap<>Nil then begin
PB:=PMap;
inc(PB, Size);
if PB^<>10 then
Count:=1
else
Count:=0;
repeat
Dec(PB);
if PB^=10 then
Inc(Count);
until (Count>NumFromEnd) or (PB=PMAP);
if PB<>PMap then
Inc(PB);
PEnd:=StrScan(PChar(PB),#13);
if PEnd=nil then begin
PEnd:=Pchar(PMap);
Inc(PEnd,Size);
end;
SetString(Result, PChar(PB), PEnd-PB);
UnmapViewOfFile(PMap);
end;
CloseHandle(MapH);
end;
CloseHandle(FileH);
end;
end;
Страницы: 1 вся ветка
Текущий архив: 2003.02.17;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.013 c