Форум » [x]Harbour » Считать текстовый файл в массив .... » Ответить

Считать текстовый файл в массив ....

Andrey: Всем привет. Столкнулся тут с проблемкой. Текстовые файлы (оплаты с банков) не всегда содержат в конце строки CHR(13)+CHR(10). Как правильно считать в массив построчно текстовые файлы ? Вариантов много, хочу найти лучший. По скорости наверно лучше: считать целиком файл в переменную FileStr() и потом построчно обрабатывать. Я делаю по Клиперному, а в хХарборе как еще можно ?

Ответов - 19

Dima: Andrey Длина строки постоянная ? Закинь такой файлик на обменник , гляну.

Pasha: По клипперному и по харборному - так не бывает. Бывают разные алгоритмы, а реализовать их можно и в клиппере, и в харборе. Как лучше: считывать весь файл в строку или завести буфер и считывать файл поблочно - это зависит от предполагаемого размера файла. Если он небольшой - несколько десятков kb (для клиппера этот размер меньше), то можно считывать сразу весь файл. Если там мегабайты - то лучше считывать поблочно. Насчет разделителя строк - надо проверять все возможные. Я к примеру проверяю сначала наличие CHR(13)+CHR(10), и если такого нет - проверяю Chr(10)

Andrey: Dima пишет: Закинь такой файлик на обменник , гляну. Да они разные... и от вас тоже разные из банков приходят... Подготовлю и вышлю. Т.к. файлы идут каждый день, то размер небольшой меньше 100Кб. Я до этого пользовался функцией из Клипера ************************************************************************* * Function : ROWS * Author : Michael Peters * Date : 09/14/90 * Usage : The text from a file is read and processed by the line. * What you are doing with the single rows within the * function is your turn. * * Notes : No blank lines are available! * A file size over 64 kB is not allowed! * See also: FTOKEN.PRG * * Example : DO ROWS WITH "C:\AUTOEXEC.BAT" * ************************************************************************** FUNCTION ROWS(cFileName) LOCAL cFileText, cLine IF "" <> FILESEEK(cFileName) cFileText := FILESTR(cFileName) TOKENINIT(@cFileText, CHR(13)+CHR(10), 2) // initialize ! @ ! DO WHILE .NOT. TOKENEND() * each row can be processed * for example converted in capital letters * cLine := TOKENNEXT(cFileText) // get next row ?? UPPER(cLine) + CHR(13) + CHR(10) ENDDO ENDIF RETURN(NIL) Хотя можно и проще сделать: cLine := FILESTR(cFileName) aFile := HB_ATokens( cLine, CHR( 13 ), .T., .T. ) // Удалить спереди знак CHR(10) FOR nI := 1 TO LEN(aFile) aFile[nI] := CHARREM(CHR(10), aFile[nI]) NEXT ................. Я пробовал до 1 Мб - файлы обрабатываются 2-3 сек. Просто вот интересно и как правильно делать эти операции ? А если лог-файлы нужно обрабатывать по 300 и более Мб. Что тогда делать ?


Dima: Andrey пишет: Подготовлю и вышлю. Да не надо уже. К каждому банку свой подход , у меня так.

Pasha: Andrey пишет: Просто вот интересно и как правильно делать эти операции ? А если лог-файлы нужно обрабатывать по 300 и более Мб. Что тогда делать ? Дык это еще зависит от того, на каком компьютере выполняется обработка. Если оперативки мало, да еще ее сьедает прожорливый антивирус, это одно, а если ее хоть залейся, много-много гиг - это другое. Использование TokenNext - это правильный подход, так как алгоритм "ползет" по строке, и ее огромная длина роли не играет. Надо исходить из наихудших возможных условий. Если это 256M с антивирусом, то лучше не делать огромных запросов на память, а считывать файл блоками по 16/32k. Если дело обстоит не так печально - можно глотать весь файл целиком.

Andrey: Спасибо большое за объяснения ! А что например делать, если нужно обработать файл 300 Мб (логи сервера) и подсчитать статистику по нему: МАХ количество посещений с каждого IP-адреса, Кол-во посещений по пути /список путей/, Кол-во типов запроса GET ххх, POST хххх и т.д. ? Исходим из того что это сервер и памяти много...

Pasha: Считывать файл размером в сотни мегабайт в строку, сколько бы ни было памяти на сервере, конечно, не стоит. Надо считывать файл блоками. Обоработал блок - считать следующий, приклеить к нему необработанный хвост с предыдущего блока, и на обработку.

santy: Можна использовать функции работы с текстовыми файлами: HB_FEof() Tests if the end-of-file is reached in the currently selected text file. HB_FGoBottom() Moves the file pointer to the last line in a text file. HB_FGoto() Moves the record pointer to a specific line in the currently selected text file. HB_FGoTop() Moves the record pointer to the begin-of-file. HB_FInfo() Retrieves status information about the currently selected text file. HB_FLastRec() Returns the number of lines in the currently selected text file. HB_FReadAndSkip() Reads the current line and moves the record pointer. HB_FreadLN() Reads the current line and without moving the record pointer. HB_FRecno() Returns the current line number of the currently selected text file. HB_FSelect() Queries or changes the currently selected text file area. HB_FSkip() Moves the record pointer in the currently selected text file. HB_FUse() Opens or closes a text file in a text file area. Можна загрузить файл в базу и там уже с ним работать.

Andrey: А примеры работы с HB_Fхххх() - есть ? santy пишет: Можна загрузить файл в базу и там уже с ним работать. А по быстродействию как будет ? Ведь обработка и запись в файл - медленная операция.... Или использовать HB_MEMIO ? А в МиниГуи HB_MEMIO использовать можно на Харборе ?

santy: Andrey пишет: А примеры работы с HB_Fхххх() - есть ? \Harbour\contrib\hbmisc\tests Относительно работы с базой, нужно пробовать.

Andrey: santy пишет: \Harbour\contrib\hbmisc\tests Спасибо !

AlexMyr: Andrey пишет: Как правильно считать в массив построчно текстовые файлы ? Можно изучить METHOD Source2Array( cSource ) CLASS HBFormatCode в harbour\contrib\hbformat\hbfmtcls.prg

Andrey: AlexMyr пишет: Можно изучить METHOD Source2Array( cSource ) CLASS HBFormatCode в harbour\contrib\hbformat\hbfmtcls.prg Кстати, а как форматировать текст своего *.prg ? Я так и не вьехал в эту утилиту....

AlexMyr: Andrey пишет: Я так и не вьехал в эту утилиту.... в командной строке hbformat file.prg

Andrey: AlexMyr пишет: в командной строке hbformat file.prg Ни чего не происходит... Не форматирует !

Dima: Andrey пишет: Не форматирует ! Форматирует !

gfilatov2002: Andrey пишет: Ни чего не происходит Этой утилите не нравятся нестандартные команды типа END WINDOW, END TOOLBAR , END TREE Если их закоментировать в тексте программы, то форматирование проходит нормально (но надо не забыть расскомментировать затем эти строки )

Andrey: Теперь понял... Нужно еще сюда добавить такие команды: @ 0,10 LABEL Label_9 WIDTH nWidth HEIGHT 40 ; @ nHeight,0 PROGRESSBAR Progress_1 ; RANGE 1,10 ; END INI

LYSK: обработка текстового файла путем загрузки его в базу, т.е. таблицу дбф - на самом деле по скорости не будет отличаться от всевозможных ухищрений с обработкой в оперативной памяти, тут самое главное - добиться чтобы строки текстового файла правильно распределились по записям базы. (delimited вам в помощь).



полная версия страницы