Форум: "Основная";
Текущий архив: 2005.11.27;
Скачать: [xml.tar.bz2];
ВнизПроцедура 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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.014 c