FREAD/FREADSTR

150 views
Skip to first unread message

John Gillen

unread,
Aug 23, 2022, 1:54:32 AM8/23/22
to Harbour Users
Prior to converting a dBASE application, I need to confirm that the FREAD or FREADSTR function can be configured to read a string from a file and stop at CR/LF or \n. This is a critical need for the application, as it reads through large text files separated into paragraphs with CR/LF or \n.

Reading x number of characters will not work as the number will, of course, vary by paragraph.

Any thoughts on this will help.

Thanks,
John

Pete

unread,
Aug 23, 2022, 2:53:25 AM8/23/22
to Harbour Users
Hello,

On Tuesday, 23 August 2022 at 08:54:32 UTC+3 johna...@gmail.com wrote:
Any thoughts on this will help.

If what you want to do is to read your text files line-by-line and process each one (or some) of those lines,
then you could look at and utilize other than FREAD** functions, more appropriate for the purpose.
In any case, to get useful  suggestions, I think you must supply more details about the task
(it'd be good also to be more specific about the "largeness" of the text files in question).

regards,
Pete



 
 

AL67

unread,
Aug 23, 2022, 3:31:54 AM8/23/22
to Harbour Users
Maybe use HBMISC  library.

SAMPLE1:
***********************
#require "hbmisc"
#include "fileio.ch"
PROCEDURE Main( cFile )
   hb_default( @cFile, __FILE__ )
   // open a text file here
   IF hb_FUse( cFile, FO_READ ) > 1
      DO WHILE ! hb_FAtEof()
         ? "line " + Str( hb_FRecNo(), 2 ) + " " + hb_FReadLn()
         hb_FSkip( 1 )
      ENDDO
      ?
      my_goto( 18 )
      my_goto( 2 )
      hb_FGoBottom()
      ?
      ? "after hb_FGoBottom() now in line # " + hb_ntos( hb_FRecNo() )
      hb_FGoTop()
      ?
      ? "after hb_FGoTop() now in line # " + hb_ntos( hb_FRecNo() )
      ?
      ? "hb_FLastRec() = " + hb_ntos( hb_FLastRec() )
      // close the file
      hb_FUse()
   ENDIF
   RETURN

STATIC PROCEDURE my_goto( n_go )
   hb_FGoto( n_go )
   ?
   ? "after hb_FGoto( " + hb_ntos( n_go ) + " )"
   ? "line " + hb_ntos( hb_FRecNo() ) + " is " + LTrim( hb_FReadLn() )
   RETURN
***************************************
SAMPLE2:
*******************
#require "hbmisc"
PROCEDURE Main( cFile )
   LOCAL oFile := TFileRead():New( cFile )
   oFile:Open()
   IF oFile:Error()
      ? oFile:ErrorMsg( "FileRead:" )
   ELSE
      DO WHILE oFile:MoreToRead()
         ? oFile:ReadLine()
      ENDDO
      oFile:Close()
   ENDIF
   RETURN
*****************

Adam

d s

unread,
Aug 23, 2022, 3:38:54 AM8/23/22
to Harbour Users

You can try this:

*
#define CRLF CHR(13)+CHR(10)
*
FUNCTION ReadCsv ()  // reading Csv file
*
LOCAL i
LOCAL cLine,nHandle,cFile
*
cFile:="somefile.csv"
IF ! FILE(cFile)
   RETURN (.F.)
ENDIF
*
nHandle:=FOPEN(cFile)
IF nHandle == -1
   RETURN (.F.)
ENDIF
*
i:=0
DO WHILE GreadR1(@cLine,nHandle)
   i++
   IF i==1   // if you have and do not need first header line
      LOOP
   ENDIF
   *
   * now you have line data in cLine
   * do what you want with cLine from somefile.csv
   *
   * get next line in loop
ENDDO
FCLOSE(nHandle)
*
RETURN (.T.)
*
*EOF-----------------------------------------------------------------

*
FUNCTION GreadR1(cstring, nhandle)
*
LOCAL ret_val := .T.
LOCAL buffer,ptr,bytes
LOCAL bufsize := 4000
LOCAL tempstring
*
cstring := []
buffer := SPACE(bufsize)
*
DO WHILE .T.
   bytes := FREAD(nhandle, @buffer, bufsize)
   tempstring := LEFT(buffer, bytes)
   IF ( ptr := AT(CRLF, tempstring) ) > 0
      cstring:=cstring+SUBSTR(tempstring, 1, ptr - 1)
      FSEEK(nhandle, -(bytes - (ptr + 1)), FS_RELATIVE)
      EXIT
   ELSE
      cstring:=cstring+tempstring
      IF bytes < bufsize
         ret_val := .F.
         EXIT
      ENDIF
   ENDIF
ENDDO
*
RETURN ret_val
*
*--------------------------------------------------GreadR1-----------
*

 Best Regards,
Simo.

Bob Burns

unread,
Aug 23, 2022, 3:59:31 AM8/23/22
to harbou...@googlegroups.com

Hi John

When I have had to work with programming languages that did not have a "read line" function I have written a low level routine to read in x characters at a time, build a temporary string and look for the CR/LF end of line marker in order to terminate the string building process for each line. Not too difficult to achieve but does add a time overhead as string handling can be quite slow.

Clipper's FREADSTR function reads in a specified number of characters up to a maximum of 65535 from which you can extract / build each line of text.

If you cannot find a satisfactory solution take a look at:

https://github.com/vszakats/hb/blob/096e855/contrib/hbmisc/fileread.prg#L17

Regards

Bob

Bob F Burns G3OOU, G-QRP 6907, @BobFBurns
Crystal Palace Radio & Electronics Club: https://cprec.chessck.co.uk/
Admin/sales site: http://www.g3oou.co.uk/
Technical site: www.qsl.net/g3oou
--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: https://groups.google.com/group/harbour-users
---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/harbour-users/ef2bf2b8-11fc-432c-856e-4edf4b2c1e74n%40googlegroups.com.

Auge & Ohr

unread,
Aug 23, 2022, 12:58:15 PM8/23/22
to Harbour Users
hi

how big is you File to read ?

i do use MEMOREAD(), MLCOUNT() and MEMOLINE().

if your File is > 2 GB than you need a "special Reader"

Jimmy

Bernard Mouille

unread,
Aug 24, 2022, 1:16:52 PM8/24/22
to Harbour Users
* FREADLINE.ch - Lecture d'une ligne d'un fichier binaire.
* --------------------------------------------------------
*
*  Function: GFReadLine()
*  Author:   Greg Lief
*  Copyright (c) 1990 Grumpfish, Inc. - All Rights Reserved
*
*  Purpose:  Read in the next string from the text file
*            (i.e., up to the next CR/LF combo)
*
*  Syntax:   GFReadLine(@<string>, <handle>)
*
*  Parameters:  <string> is the character variable which will
*               will hold the string.  NOTE: this must be
*               passed by reference (preceded by a "@")!!
*
*               <handle> is the file handle to read the string
*               from.  This would have been returned from either
*               FOPEN() or FCREATE().
*
*  Returns:  Logical value: .T. if successful, .F. if EOF()
*
* Le 5 février 2012, j'ai modifié pour la mettre sans warning.
*
*******************************************
FUNCTION FREADLINE( mstring, handle, nFin )
*******************************************
*
LOCAL ptr
LOCAL bytes
LOCAL tempstring
LOCAL bufsize := 255
LOCAL buffer  := SPACE( bufsize )
LOCAL crlf    := CHR( 13 ) + CHR( 10 )
LOCAL ret_val := .T.
LOCAL nFinSeek := 1
*
mstring := []
*
IF nFin <> NIL          && Fichier avec fin de ligne LF
 crlf := CHR( 10 )
 nFinSeek := 0
ENDIF
*
DO WHILE .T.
 bytes      := FREAD( handle, @buffer, bufsize )
 tempstring := LEFT( buffer, bytes )
 ptr        := AT( crlf, tempstring )
 *
 IF ptr > 0
  mstring := mstring + substr( tempstring, 1, ptr - 1 )
  fseek( handle, -( bytes - ( ptr + nFinSeek ) ), 1 )
  EXIT
 ELSE
  mstring := mstring + tempstring
  **

  IF bytes < bufsize
   ret_val := .F.
    EXIT
  ENDIF
  **
 ENDIF
 *
ENDDO
*
RETURN ret_val

Regards,
Bernard.


Reply all
Reply to author
Forward
0 new messages