Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Процедура ReadLn [D7, WinXP]


Страницы:   1 2

alex870 ©   (2005-11-02 12:10:00) 

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


Digitman   (2005-11-02 15:44:00) [1]

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

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


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


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

вот тут поспорить не могу :-)!
Я не стал (пока) писать метод для своего класса (я думаю скорость от этого не изменится), а написал свою функцию:
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:06:00) [3]


> alex870   (02.11.05 15:02) [20]


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


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


alex870   (2005-11-02 15:02:00) [4]


> Вообще есть там интересный флаг
> 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. Была мысль, что в ней можно задать формат конца строки.


han_malign   (2005-11-02 14:36:00) [5]


> Как написана 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].


Digitman   (2005-11-02 13:32:00) [6]


> Sapersky   (02.11.05 13:24) [17]


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

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


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

В D7 есть ф-я SetLineBreakStyle.


Digitman   (2005-11-02 13:17:00) [8]


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


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


alex870   (2005-11-02 13:13:00) [9]


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

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


Digitman   (2005-11-02 13:09:00) [10]


> alex870   (02.11.05 12:55) [12]


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

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

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


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

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


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


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

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


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


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

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


Digitman   (2005-11-02 12:53:00) [14]


> alex870   (02.11.05 12:44) [7]


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

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

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


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


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

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


Lexer   (2005-11-02 12:46:00) [16]

Попробуй ради эксперимента:
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:44:00) [17]


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

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

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


Digitman   (2005-11-02 12:43:00) [18]


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


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


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


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


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

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


Digitman   (2005-11-02 12:40:00) [20]


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


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

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо