Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.11.27;
Скачать: CL | DM;

Вниз

Процедура ReadLn   Найти похожие ветки 

 
alex870   (2005-11-02 12:10) [0]

Уважаемые мастера! Кто-нибудь знает как написана процедура ReadLn. В System.pas я её не нашел, однако мне хотелось бы переделать её, чтобы она видила конец строки только если #10, а не #13#10. Процедурой Read пользоваться неприемлимо, т.к. обрабатывается очень большой текстовый файл (десятки мегабайт).


 
Digitman ©   (2005-11-02 12:17) [1]


> Процедурой Read пользоваться неприемлимо, т.к. обрабатывается
> очень большой текстовый файл (десятки мегабайт).


однако, прелюбопытная причинно-следственная связь)..


 
alex870   (2005-11-02 12:30) [2]


> Digitman ©
> однако, прелюбопытная причинно-следственная связь)..

Да, может я просто пользоваться не умею, но я имел в виду, что если читать файл побайтно (написав код на дельфи с использованием Read)- это займет очень много времени. Я предполагаю, что ReadLn написана на ассемблере. Сам я такую процедуру на asm"е не напишу, но имея небольшие знания ассемблера могу поправить уже готовую. Поправьте меня если я не прав, и вообще вы только орехи в вопросах ищите или помочь можете


 
Lexer ©   (2005-11-02 12:32) [3]

Как написана ReadLn - это вопрос к Borland, эта процедура встроена в компилятор.


 
Digitman ©   (2005-11-02 12:40) [4]


> и вообще вы только орехи в вопросах ищите или помочь можете


файл-то большой ?

я к тому, что может и проблема-то не существует, ибо достаточно будет задействовать TStringStream


 
alex870   (2005-11-02 12:40) [5]


> Lexer ©   (02.11.05 12:32) [3]


> Как написана ReadLn - это вопрос к Borland, эта процедура
> встроена в компилятор

Очень интересно! Может тогда поможете, другим путем направите?
Проблема у меня такая: в текстовом файле имеется огромное число строк, каждая из них заканчивается #10, но некоторые строки имеют в середине сочетания #13#10, что для программы, создавшей этот файл не являлось концом строки. Как мне сделать быструю обработку строк этого файла, пропуская сочетания #13#10, а обрабатывая только *#10, где *-любой другой символ кроме #13.


 
Digitman ©   (2005-11-02 12:43) [6]


> некоторые строки имеют в середине сочетания #13#10, что
> для программы, создавшей этот файл не являлось концом строки


интересно, а чем же тогда они являются для этой программы ?


 
alex870   (2005-11-02 12:44) [7]


> Digitman ©   (02.11.05 12:40) [4]

> файл-то большой ?

Да, файл - это лог Kerio Winroute, может доходить размером до гигабайта. Я пробовал анализировать ~198Mb С помощью ReadLn занимает около 30 сек - это меня устраивает, т.е. даже если на анализ максимального размера уйдет 3 мин.


 
Lexer ©   (2005-11-02 12:46) [8]

Попробуй ради эксперимента:
var
 s: TStrings;
begin
 s := TStringList.Create;
 try
   s.LoadFromFile ("myfile");
   // теперь s [i] содержит i-ую строку из файла
 finally
   s.Free;
 end;
end;


Посмотрел модуль Classes, кажетя строка переводится при нахождении #13 или #10. (TStrings.SetTextStr)


 
alex870   (2005-11-02 12:48) [9]


> интересно, а чем же тогда они являются для этой программы
> ?

А вот хрен его знает!!! примерно в 99% случаев их там нет, но иногда они появляются (сочетания #13#10). Winroute анализирует свои логи правильно, но даже он, когда открывает просмотр лога, то реагирует на эти сочетания и переносит половину строки на новую.


 
Digitman ©   (2005-11-02 12:53) [10]


> alex870   (02.11.05 12:44) [7]


это ты error.log имеешь ввиду ?

что-то не вижу я там никаких #10 ..

везде и всюду там как разделители строк - #13#10 ..


 
alex870   (2005-11-02 12:54) [11]


> Lexer ©   (02.11.05 12:46) [8]

Спасибо за пример! А как он поможет решить проблему, описанную в [5]. Т.е. не видить завершение строки при нахождении #13#10, а тольго при нахождении *#10, где * - не #13?


 
alex870   (2005-11-02 12:55) [12]


> это ты error.log имеешь ввиду ?

нет http.log (kerio 6.1.0). Там конец строки именно #10.


 
alex870   (2005-11-02 13:03) [13]

Может можно узнать на какой последовательности обрезала строку ReadLn? Тогда я бы поступил так: если #13#10 - то еще один ReadLn, а потом склееваим. Таких строк не очень много.


 
Digitman ©   (2005-11-02 13:09) [14]


> alex870   (02.11.05 12:55) [12]


смотреть http.log не буду, хотя и весьма сомневаюсь в истинности твоих утверждений..

TStringList и TStringStream для таких объемов, конечно же, не подходят.

напиши своего наследника TFileStream, объяви и реализуй в нем метод ReadLn ..


 
alex870   (2005-11-02 13:13) [15]


> напиши своего наследника TFileStream

А где этот TFileStream хранит данные, в памяти? (Честно говоря плохо этот вопрос себе представляю) не поплохеет ему от размера в гигабайт?


 
Digitman ©   (2005-11-02 13:17) [16]


> где этот TFileStream хранит данные, в памяти?


в том и вся прелесть, что  TFileStream как наследник THandleStream не считывает разом и не хранит образ файла в памяти, а считывает фрагменты файла именно "по требованию" - с тек.позиции Read(в такой-то буфер, столько-то)


 
Sapersky   (2005-11-02 13:24) [17]

В D7 есть ф-я SetLineBreakStyle.


 
Digitman ©   (2005-11-02 13:32) [18]


> Sapersky   (02.11.05 13:24) [17]


для столь якобы уникального случая сия ф-ция никак не канает) ..

здесь же проверка нестандартного условия требуется - если встретился #10 и непосредственно перед ним имеется #13, то - фиг знает что, иначе - перенос строки


 
han_malign ©   (2005-11-02 14:36) [19]


> Как написана ReadLn - это вопрос к Borland, эта процедура встроена в компилятор.

- Ну почему же - System.ReadLine/_ReadXString  - но перекомпилировать System довольно проблематично, хотя не невозможно...
Вообще есть там интересный флаг
tfCRLF   = $1;    // Dos compatibility flag, for CR+LF line breaks and EOF checks,
который устанавливается в DefaultTextLineBreakStyle и см. Sapersky(02.11.05 13:24)[17].


 
alex870   (2005-11-02 15:02) [20]


> Вообще есть там интересный флаг
> tfCRLF   = $1;    // Dos compatibility flag, for CR+LF line
> breaks and EOF checks,
> который устанавливается в DefaultTextLineBreakStyle и см.
>  Sapersky(02.11.05 13:24)[17].

Да, но как изменением этого флага я решу свою задачу см. [5]. Я попробовал способ, который подсказал

> Digitman ©   (02.11.05 13:09) [14]

Работает, но раз в 10 медленее, чем Readln. Искал в MSDN, но не нашел функцию аналогичную Readln. Была мысль, что в ней можно задать формат конца строки.


 
Digitman ©   (2005-11-02 15:06) [21]


> alex870   (02.11.05 15:02) [20]


> Работает, но раз в 10 медленее, чем Readln


значит - лажа в алгоритме.


 
alex870   (2005-11-02 15:18) [22]


> значит - лажа в алгоритме

вот тут поспорить не могу :-)!
Я не стал (пока) писать метод для своего класса (я думаю скорость от этого не изменится), а написал свою функцию:
function MyReadLn(FS: TFileStream;var Str: WideString;var Position: Int64): Integer;
var
Temp : array of char;
Buff : Char;
R : boolean;
L : Integer;
begin
R := False;
L := 0;
while R = False do
begin
if FS.Read(Buff,1) <> 0 then
 begin
  Inc(L);
  if (Buff = #10) and (Temp[High(Temp)] <> #13) then R := True else
   begin
    if Length(Temp) <> 0 then
    SetLength(Temp,High(Temp)+2) else SetLength(Temp,1);
    Temp[High(Temp)] := Buff;
   end;
 end else R := True;
end;
Str := Trim(String(Temp));
Position := Position+L;
Result := Length(Str);
end;

конечно не очень красиво, но я пока не вижу, что может кардинально изменить скорость.


 
Digitman ©   (2005-11-02 15:44) [23]

разумные (!) параметры кэширования данных при операциях обращения к файлу ощутимо изменят производительность алгоритма

см. все касаемое кэширования данных при операциях ввода/вывода



Страницы: 1 вся ветка

Текущий архив: 2005.11.27;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.031 c
2-1131531380
DelphiLexx
2005-11-09 13:16
2005.11.27
TFIBQuery


14-1130395075
Layner
2005-10-27 10:37
2005.11.27
Сервис, таймер в нем отказывается работать...


1-1130844137
ai3000
2005-11-01 14:22
2005.11.27
Мега-БПЛ


2-1131107194
syte_ser78
2005-11-04 15:26
2005.11.27
сетевой доступ к баз Paradox7


14-1130915005
Saruwatari
2005-11-02 10:03
2005.11.27
Кто что знает об ипотеке поделитесь мыслями...