Reading a file into a string?

Just starting out? Need help? Post your questions and find answers here.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by PB.

Anyone know how to read an entire file into a string?
In Visual Basic, you would do it like so:

file$="c:\example.exe"
Open file$ For Binary As 1
buffer$ = Space(LOF(1)) ' Create buffer$ of file size
Get 1, 1, buffer$ ' Fill buffer with file contents
Close 1

Then, buffer$ would hold the data of file$...

I'm sure it has something to do with PureBasic's "ReadMemory"
command -> ReadMemory(*MemoryBuffer, LengthToRead) <-
but I'm not entirely sure how to use it...


Edited by - PB on 20 September 2001 04:15:15
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Mr.Skunk.

This example Should work :

If ReadFile(1,"c:\system.1st") ; only to...
length.l=Lof() ; determine the length of the file.

*Buffer.l=AllocateMemoryBank(1,length,0) ; allocate a buffer whith the length of the string
If *Buffer ; if the allocation failled *Buffer if 0 else *Buffer is the address of the buffer
ReadMemory(*Buffer,length) ; fill the buffer with the file
EndIf

CloseFile(1)
EndIf

Hope it helps

Mr Skunk

Mr Skunk's PureBasic Web Page
http://www.skunknet.fr.st

Edited by - mr.skunk on 06 September 2001 01:12:54
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Mr.Skunk.

Hi

To get the data, you can use the PeekS() command

a$=PeekS(*Buffer) ; (PeekS means PeekString)

Mr Skunk

Mr Skunk's PureBasic Web Page
http://www.skunknet.fr.st
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Paul.

Your code works fine here, other than you forgot DrawingOutput(WindowID()) before the Locate command.

It does crash every time if I use a large file though.
Maybe you are overflowing the buffer ??
Is there a Windows limit (or PB limit) on the size of a String ??
The error seems to occur when you try to load a large buffer into the string:
Target.s = PeekS(*Buffer)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Mr.Skunk.

Hi,

For the "0" character at the end of a string, it is added by PB itself each time you use a string.

For a text file, each line may be ended by chr(13) only, so you will have all the file in your string if you don't check for ch(13) yourself...

There is a PB limit to 5000 characters you can define for a string a each time.
in fact 4999+chr(0)=5000
but you can define your string in more than once to pass the limit.

example :
a$=space(6000) will crash
and
a$=space(4999)
a$=a$+space(1001)
works fine

It's due to that PB allocates a max of 5000 bytes of memory each time for strings.

Hope it helps...


Mr Skunk

Mr Skunk's PureBasic Web Page
http://www.skunknet.fr.st


Edited by - mr.skunk on 28 September 2001 07:39:14
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Paul.

Not sure what your using this for but you could read in the data, process it and then put it back to disk. That way you don't need it all in one string.

Code: Select all

NewList dat.s()

If ReadFile(1,"nfo.txt")
  While eof()=0
    AddElement(dat())
    dat()=ReadString()
  Wend
  CloseFile(1)
EndIf

bad$="~!@#$%^&*()_+=-`"

For startbad=1 To len(bad$)
  ResetList(dat())
  While NextElement(dat())
    badchar$=mid(bad$,startbad,1)
    mystring$=StripAll(dat(),badchar$)
    dat()=mystring$
  Wend
Next

If CreateFile(1,"result.txt")
  ResetList(dat())
  While NextElement(dat())
    WriteStringN(dat())
  Wend
  CloseFile(1)
EndIf

End
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.
Paul, hello. Thanks for the reply, Mr Skunk answered about the size. 5000 characters being a size constraint is very suprising after coming from a compiler with no string space limits. I cans ee I am going to have to re-learn a lot of things (grin).

I could use your example on the NFO text file I am using but that's just a text case. I have a lot more processing to do on the actual text file that I am using in the cataloguer.

Might try figuring out how to use a linked list and read one line at a time from the text file if that is possible. Looks like I shall be begging people to write a whole lot of function libraries for what I am missing :):)

Have a great day

Fangles
The 5000 bytes limits is inherited from the AmigaOS architecture which doesn't supports the FLAT memory model. Anyway, I could change it for Windows (using the upper memory space). But it's not clean. BTW, reading a full file into a string is really a bad thing (Sorry !) :-D. Better use ReadLine() or like command, it will be more efficient.



Fred - AlphaSND
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Pupil.

Fangbeast, if the files that you want to read contains only textlines, with less than 5000 characters on each line, you could try the ReadString() function.
So your code could look something like this:

Code: Select all

...
bigstring$=""
EOL$=Chr(13)+Chr(10)
if ReadFile(0,filename$)
  While not Eof()
    tmp$=ReadString() ; now either you can process this string directly or..
    bigstring$=bigstring$+tmp$+EOL$ ; do like this and add up all lines into one string.
                                    ; You might want to skip the EOL$(?)
  Wend
EndIf

As always i haven't tried my own code but it should work :wink:
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by PB.
BTW, reading a full file into a string is really a bad thing (Sorry !) :-D. Better use ReadLine() or like command, it will be more efficient.
I personally need to read a file into a string when the file
is binary (*.exe) rather than text (*.txt). What would be the
best way to do this without loading it into a string?
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Pupil.
I personally need to read a file into a string when the file
is binary (*.exe) rather than text (*.txt). What would be the
best way to do this without loading it into a string?
Perhaps like this:

Code: Select all

...
if ReadFile(0,filename$)
  tmp.s = Space(Lof()+1) ; Where space is a procedure that returns a string of
                         ; length 'Lof()+1' filled with  chars.
  ReadMemory(@tmp, Lof()); Read binary into string reserved space.
EndIf
...
This is just a suggestion. Like Fred hinted before, it's probably not an advicable way of doing things, but it's doable;)
The code should most likely work on binaries less than 5000 bytes, i can't really say how things are when strings get longer than that because i've no grip on how the sting allocation works internally(if it allocates in an continuous manner or if bits of the string are linked together).

Haven't tested code, thought you might;)

/Pupil
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Mr.Skunk.

As exe are binary, they don't have only printable characters,
i think the best way is to use allocatememory() and readmemory()
then you can use the peekL()peekB()... commands to read the file.


Mr Skunk

Mr Skunk's PureBasic Web Page
http://www.skunknet.fr.st
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by gnozal.
Paul, hello. Thanks for the reply, Mr Skunk answered about the size. 5000 characters being a size constraint is very suprising after coming from a compiler with no string space limits. I cans ee I am going to have to re-learn a lot of things (grin).

I could use your example on the NFO text file I am using but that's just a text case. I have a lot more processing to do on the actual text file that I am using in the cataloguer.

Might try figuring out how to use a linked list and read one line at a time from the text file if that is possible. Looks like I shall be begging people to write a whole lot of function libraries for what I am missing :):)

Have a great day

Fangles
The 5000 bytes limits is inherited from the AmigaOS architecture which doesn't supports the FLAT memory model. Anyway, I could change it for Windows (using the upper memory space). But it's not clean. BTW, reading a full file into a string is really a bad thing (Sorry !) :-D. Better use ReadLine() or like command, it will be more efficient.



Fred - AlphaSND
Fred, what ReadLine() command?? I can't find it anywhere in the documentation??? (scratching head)

Fangles
In my experience, reading a full (text) file into a string [GET file, 1, String$] is much more faster than readline [DO : LINE INPUT String$ : LOOP UNTIL EOF]. I use it with PowerBasic. It seems that reading a text file line by line is slower with PureBasic than PowerBasic, so I'd like to read a full (text) file into a string, this means no size limit for strings. Please Fred...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by gnozal.

In my experience, reading a full (text) file into a string [GET file, 1, String$] is much faster than readline [DO : LINE INPUT String$ : LOOP UNTIL EOF]. I use it with PowerBasic. It seems that reading a text file line by line is slower with PureBasic than PowerBasic, so I'd like to read a full (text) file into a string, this means no size limit for strings. Please Fred...
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Rings.

Fred wrotes:
The 5000 bytes limits is inherited from the AmigaOS architecture which doesn't supports the FLAT memory model. Anyway, I could change it for Windows (using the upper memory space). But it's not clean. BTW, reading a full file into a string is really a bad thing (Sorry !) :-D. Better use ReadLine() or like command, it will be more efficient.
Fred - AlphaSND

Okay, some compatibility with the 14 year old Amiga-structure-model(i used a A1000 many years ago..).
BTW it is often very usefull to read a HOLE file into memory,for example
compressing,depacking,scrambling,CopytoAnotherResource,and and and....
I'm Sure that there must be a Limit, but please not onto 5 KB.
2 MB are for good , but lets discuss the thing.




Siggi
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by fred.
Okay, some compatibility with the 14 year old Amiga-structure-model(i used a A1000 many years ago..).
BTW it is often very usefull to read a HOLE file into memory,for example
compressing,depacking,scrambling,CopytoAnotherResource,and and and....
I'm Sure that there must be a Limit, but please not onto 5 KB.
2 MB are for good , but lets discuss the thing.
For compressing, Scrambling etc.. you won't use a big string I guess. The memoryBank library is made for such things. String must be used for String only, not for Memory buffer allocation. I will update the buffer size to have unlimited size, but think than using string for binary stuffs is bad.

Fred - AlphaSND
Post Reply