April 28, 2024, 01:24:42 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Problem w/ file,bfile,write,read,put,get

Started by LarryMc, June 27, 2007, 01:26:52 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

June 27, 2007, 01:26:52 PM Last Edit: June 27, 2007, 03:12:11 PM by Larry McCaughn
Help file says:
QuoteIn a binary file all data is written in raw form and will occupy the full size of the dimensioned variable. For example a standard STRING is 255 bytes:

DEF myfile as BFILE
DEF str as STRING
str = "hello"
IF OPENFILE(myfile, "C:\\temp\\temp.bin", "W") = 0
    WRITE myfile, str
    CLOSEFILE myfile
ENDIF

The length of the file will be 255 bytes in this case.
Running that program exactly as it is gives a file of length 5; not 255.  This flaw causes reads to not be processed properly. 
QuoteHowever using an ASCII file the WRITE statement will only write the contents of the string and automatically terminate the string with a linefeed/carriage return pair.

DEF myfile as FILE
DEF str as STRING
str = "hello"
IF OPENFILE(myfile, "C:\\temp\\temp.txt", "W") = 0
    WRITE myfile, str
    CLOSEFILE myfile
ENDIF

The length of the file would be 7 bytes in this case and be loadable in any text editor.

Works as advertised
If I modify the bfile code to read like this:
QuoteDEF myfile as BFILE
DEF str as STRING
IF OPENFILE(myfile, "C:\\temp\\temp.bin", "R") = 0
    READ myfile, str
    CLOSEFILE myfile
ENDIF
Print str
Nothing prints.  I have to insert:
Quotestr=space$(254)
before the read to get it to print.  I shouldn't have to do that.

If I modify the first code example to use a PUT instead of a WRITE:
QuoteDEF myfile as BFILE
DEF str as STRING
str = "hello"
IF OPENFILE(myfile, "C:\\temp\\temp.bin", "W") = 0
    put myfile,1, str
    str = "good-bye"
    put myfile,2, str
    str = "so long how do you do"
    put myfile,3, str
    CLOSEFILE myfile
ENDIF
After the 1st put I have a file length of 5.
When I do the 2nd put I wind up with a file length of 16 (2 x len of 2nd str)
When I do the3rdput I wind up with a file length of 63 (3 x len of 3rd str)
In my opinion I should have 3 records each with 254/255 characters since I was using a string variable type AND there is no parameter for me to set for record size.
Now if I modify the program to use GET to read the file:
QuoteDEF myfile as bFILE
DEF str as STRING

IF OPENFILE(myfile, "C:\\temp\\temp.bin", "r") = 0
    get myfile,1, str
   print str
    get myfile,2, str
   print str
    get myfile,3, str
   print str
    CLOSEFILE myfile
ENDIF
Nothing is read or printed because the str variable was initialize to some size AND there is no parameter to set for record size.
If i preset using:
Quotestr = space$(254)
and run this:
QuoteDEF myfile as bFILE
DEF str as STRING

IF OPENFILE(myfile, "C:\\temp\\temp.bin", "r") = 0
    str = space$(254)
    get myfile,1, str
   print str
    str = space$(254)
    get myfile,2, str
   print str
    str = space$(254)
    get myfile,3, str
   print str
    CLOSEFILE myfile
ENDIF
I get 'hello' for the 1st GET with no padding
I get a blank string 254 characters long for 2 and 3

If I change the initialization to the length of the 2nd string - 8
Quotestr = space$(8)
the results become:
I get 'hello' for the 1st GET with no padding
I get 'good-bye' for the 2nd GET with no padding
I get a blank string 254 characters long for 3rd

If I change the initialization to the length of the 3nd string - 21
Quotestr = space$(21)
the results become:
I get 'hello' for the 1st GET with no padding
I get a blank string 0 characters long for the 2nd GET
I get  "so long how do you do" for the 3rd with no padding

The bottom line for the GETs is that the only way I can get the correct information for sure is to initialize to the length of the data.  That means I need to know the length of the data before I can read the data.

I looked in the source file and there are some functions that start with underscores that have a size parameter that is being passed.

Did maybe the PUT/GET commands not get properly updated in a release?

Also the BFILE READ/WRITE commands?

Edit: And I get the same results in IBPro.
Larry

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Yes that is because the documentation is wrong, not the language ;).   It works as it is supposed to.

GET and PUT are meant for UDT records, in the old BASIC sense of a flat file binary record set.  So if your string is in a UDT then it will be written to it's dimensioned length.

If you for some reason want to write a string to 255 characters then just use the raw form of WRITE...

_WRITE(file, var, length)

_WRITE(myfile, mystring, 255)

Ionic Wind Support Team

LarryMc

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library