[Implemented] ReadString with optional length parameter

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

[Implemented] ReadString with optional length parameter

Post by PB »

I was parsing a directory of files and needed to read the starting bytes of
each, and I was using ReadString to grab the bytes and then using Left to
check for specific values, and it occurred to me that an optional length
parameter would be handy, much like how PeekS works. Because if the
file I'm reading with ReadString has a LOT of text before an end-of-line
character is found, then the read is using far more memory than it should
be (I'm actually only checking the first 5 bytes of the file, you see).

Or, ideally, I'd like to see a command for files something like this:

text$=ReadOffsetString(#file,startpos,length)

This would be very handy for parsing files where the information needed
is always located in the same offset positions. This is what I'm using now,
but surely a native command would be much faster? :)

Code: Select all

Procedure.s ReadOffsetString(file$,startpos,length)
  f=ReadFile(#PB_Any,file$)
  If f
    If startpos<>0 : FileSeek(f,startpos) : EndIf
    text$=ReadString(f) : CloseFile(f)
    If length<>0 : text$=Left(text$,length) : EndIf
  EndIf
  ProcedureReturn text$
EndProcedure
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Perhaps a good suggestion.

FYI, this is the way I would do it.

Code: Select all

Global text$
; Read a string from an offset in a file - filename, offset to start at, length to read
Procedure ReadOffsetString(file$,startpos,length) 
  *MemoryBuffer = AllocateMemory(length+1)
  opened.l =  ReadFile(#PB_Any,file$)
  If opened
    FileSeek(opened,startpos-1) 
    f = ReadData(opened, *MemoryBuffer, length)
    If f = length 
      text$ = PeekS(*MemoryBuffer,f)
      ProcedureReturn #True 
    EndIf
    CloseFile(opened)  
  EndIf    
  ProcedureReturn #False
EndProcedure 
 

OpenFile(8,"Testfile.Txt")
WriteString(8,"This is the text I want to find: ABCDEFG")
CloseFile(8)

If ReadOffsetString("Testfile.Txt",34,7)
  MessageRequester("Debug","I just offset read: " + Text$, #MB_ICONINFORMATION)
EndIf  

If ReadOffsetString("Testfile.Txt",13,4)
  MessageRequester("Debug","I just offset read: " + Text$, #MB_ICONINFORMATION)
EndIf  

End
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

I wouldn't allocate the memory on the heap in this special case and also a global string maybe is not needed. Also you do seek within the file bytewise and not stringwise. So such a function should follow PB's ReadString() logic. ;)
A little update out of my head ...

Code: Select all

; // not supporting Unicode in this quick state
Procedure.s ReadOffsetString(FileNo.l, startpos, length)
  protected tempstring.s
  If IsFile(FileNo)
    tempstring = ReadString(FileNo)
    If tempstring 
      ProcedureReturn PeekS(@tempstring+(startpos-1), length)
    EndIf
  EndIf   
  ProcedureReturn ""
EndProcedure 
Check out OOP support for PB here!
maw

Post by maw »

Why use ReadString at all if you know you just want the first 5 bytes?

Code: Select all

string$ = Space(5)
ReadData(0, @string$, 5)
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> Why use ReadString at all if you know you just want the first 5 bytes?

True, but my request did also mention being able to get text from any given
offset too. :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
maw

Post by maw »

PB wrote:True, but my request did also mention being able to get text from any given offset too. :)
Well, I was concentrating on this:
(I'm actually only checking the first 5 bytes of the file, you see)
And for that there would be no point in using ReadString.
inc.
Enthusiast
Enthusiast
Posts: 406
Joined: Thu May 06, 2004 4:28 pm
Location: Cologne/GER

Post by inc. »

But using readstring() in the function above doesnt make the output differernt when reading the first string at loc(x,0), but "beside" that it makes offsetreading strings more comfortable within textfiles else than Loc(x,0).
Check out OOP support for PB here!
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Post by nco2k »

i think an optional length parameter would be a very good thing, to have the maximum flexibility and choice while coding. i was asking the same request, some time ago. :)

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
Post Reply