Форум » Для флейма » Чтение файла построчно » Ответить

Чтение файла построчно

SadStar2018: После трехлетнего перерыва вернулся к Харбор/МиниГУИ Понадобилось обрабатывать построчно большие текстовые файлы - несколько сот Кб Почитал форум - вроде удобного средства построчного доступа так и не появилось (?) Тогда я сочинил класс StringFileReader по синтаксису из TTimerClass.prg. Если чего не понял - извиняйте. Работаю с ним так [pre2] oReader:=StringFileReader():New() // перебрать строки файла 1 if oReader:OpenFile(cFile) DO WHILE oReader:NextString() st:=alltrim(oReader:cString) .... обработка строки .... END DO oReader:CloseFile() wMain.EditBox_1.Value:=wMain.EditBox_1.Value+"Обработан Файл данных ["+cFile+"]"+CRLF else wMain.EditBox_1.Value:=wMain.EditBox_1.Value+"Файл данных ["+cFile+"] не прочитан !"+CRLF endif [/pre2] Т.е. после того как oReader:NextString() вернет .T. - забираю готовую строку из oReader:cString --- сам код класса -------------------------------- [more] [pre2] #include "common.ch" #include "hbclass.ch" CLASS StringFileReader DATA cString INIT "" //возвращаемая строка PROTECTED: DATA hFile INIT -1 DATA nPos INIT 0 //позиция начала чтения следующей строки DATA cFile INIT "" //имя открытого файла DATA ErrorCode INIT 0 DATA Ok INIT .F. EXPORTED: METHOD OpenFile(cFile) METHOD CloseFile() METHOD Reset() METHOD NextString() METHOD IsOk() ENDCLASS //------------------------------------- METHOD Init( ) CLASS StringFileReader ::nPos:=0 RETURN Self //------------------------------------- PROCEDURE Destroy() CLASS StringFileReader if ::hFile > -1 FClose(::hFile) endif ::nPos:=0 ::cFile:="" ::cString:="" RETURN //------------------------------------- METHOD OpenFile(cFile) CLASS StringFileReader local nHandle if ::hFile > -1 ::CloseFile() endif nHandle := FOPEN(cFile, 0) // 0 FO_READ Open for reading (default) if nHandle=-1 //error ::ErrorCode:=FERROR() ::Ok:=.F. else ::hFile :=nHandle ::Ok:=.T. ::cFile:=cFile ::nPos:=0 endif RETURN ::Ok //------------------------------------- METHOD CloseFile() CLASS StringFileReader ::Ok := FClose(::hFile) if ::Ok ::hFile:=-1 ::cFile:="" endif RETURN ::Ok //------------------------------------- METHOD IsOk() CLASS StringFileReader local Ok:=::Ok RETURN Ok //------------------------------------- METHOD Reset() CLASS StringFileReader ::nPos:=0 ::Ok:=.T. RETURN ::Ok //------------------------------------- METHOD NextString() CLASS StringFileReader #define F_BLOCK 256 #define CRLF chr(13)+chr(10) local cBuffer := SPACE(F_BLOCK) local nReaded local nMax:=FSeek(::hFile,0,2) //2 FS_END Seek from end of file local Pos1:=::nPos local n1:=FSeek(::hFile,Pos1,0) //Seek from beginning of file ::Ok:=.F. if Pos1>nMax ::cString:="" else nReaded:=FREAD(::hFile, @cBuffer, F_BLOCK) if nReaded>0 n1:=hb_At(CRLF, cBuffer) if n1>0 ::cString:=left(cBuffer,n1-1) ::nPos:=pos1+n1+2-1 //позицию else ::cString:=left(cBuffer,nReaded) ::nPos:=nMax+1 endif ::Ok:=.T. endif endif return ::Ok [/pre2] [/more] Была задумка и коды ошибок обрабатывать - но утилита заработала как надо и стало лень. ----------------- сюда пишу т.к. не могу оценить важность темы. Может - шлак. Тогда пусть грохнет админ. Если тема полезная - предлагаю знатокам доработать класс.

Ответов - 10

Dima: SadStar2018 пишет: Понадобилось обрабатывать построчно большие текстовые файлы - несколько сот Кб Разве это не подходит ? 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.

SadStar2018: В моем дистрибутиве MiniGUI-2017-12 таких функций нет.

PSP: Эти функции в харборе. См. contrib\hbmisc\hb_f.c


Haz: SadStar2018 пишет: В моем дистрибутиве MiniGUI-2017-12 таких функций нет. Помимо этих функций в харбуре есть класс TFileRead(), который тоже читает построчно [pre2] METHOD New( cFile, nSize ) // Create a new class instance METHOD Open( nMode ) // Open the file for reading METHOD Close() // Close the file when done METHOD ReadLine() // Read a line from the file METHOD Name() // Retunrs the file name METHOD IsOpen() // Returns .T. if file is open METHOD MoreToRead() // Returns .T. if more to be read METHOD Error() // Returns .T. if error occurred METHOD ErrorNo() // Returns current error code METHOD ErrorMsg( cText ) // Returns formatted error message PROTECTED: METHOD EOL_pos() [/pre2]

SadStar2018: Скачал hb3 - https://sourceforge.net/projects/harbour-project/files/binaries-windows/nightly/harbour-nightly-win.7z/download Делаю поиск по всем файлам. hb_freadln упоминается только в ChangeLog.txt TFileRead не упоминается совсем. Скачал sources https://sourceforge.net/projects/harbour-project/files/source/3.0.0/harbour-3.0.0-src.zip/download Делаю поиск по всем файлам. TFileRead упоминается только в ht_class.txt HB_FREADLN упоминается только в hb_f.c И что дальше? Расчитывал найти lib или prg.

Pasha: В поставке minigui библиотеки hbmisc действительно нет. А в hb3 она есть: см. lib\win\mingw\libhbmisc.a Она содержит и функции hb_f*, и класс TFileRead Сырцы находятся в папке contrib\hbmisc

PSP: SadStar2018 пишет: И что дальше? Расчитывал найти lib или prg. Сырцы: https://github.com/harbour/core/archive/master.zip Чтобы получить lib, нужно собрать с помощью bcc. Как собрать, описано в Readme.md

gfilatov2002: Pasha пишет: В поставке minigui библиотеки hbmisc действительно нет. Ощибочка вышла Эта contrib библиотека всегда была в дистрибутиве minigui

Vlad04: Чтение текстовых файлов построчно cFileText := TFileRead():New( cFileName ) cFileText:Open() WHILE cFileText:MoreToRead() cLine:= cFileText:ReadLine() в хХарбоур 1.0 применял и так же использую в Minigui

Pasha: gfilatov2002 пишет: Ощибочка вышла Эта contrib библиотека всегда была в дистрибутиве minigui Да, есть. Проглядел



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