Test load save a File

New to FreeBASIC? Post your questions here.
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Test load save a File

Post by Löwenherz »

Hello .. I have Made a simple example for Testing: perhaps anybody can Check If thats the correct way for loading saving a File with Put / get? Thanks

Code: Select all

' load and save output correct?
' put / get
'
' file: 1a-calc2.bas
'Dim As Integer x = 2025
'Dim As Integer y = 365
'Dim As Integer r = x*y-140
'Dim As String s 
's = "result for our days on earth: " + Str(r)
'Print s
'sleep 

Sub savemyfile(pfilename As String,p As String)
    Dim As Long nn=Freefile
    If Open (pfilename For Binary Access Write As #nn)=0 Then
        Put #nn,,p
        Close
    Else
        Print "Unable to save " + pfilename : Sleep : End
    End If
End Sub

Function loadmyfile(pfilename As String) As String
   Dim As Long  ff=Freefile
   If Open (pfilename For Binary Access Read As #ff)=0 Then
    Dim As String stext
    If Lof(ff) > 0 Then
      stext = String(Lof(ff), 0)
      Get #ff, , stext
    End If
    Close #ff
    Return stext
Else
  Print "Unable to load " + pfilename:Sleep:End 
  End If
End Function

Dim As String st=loadmyfile("1a-calc2.bas")
Print st


savemyfile("simplecalc2.txt",st)

print loadmyfile("simplecalc2.txt")
sleep
 
Or If there's another approach for setting Up I am glad to See .. thx
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Test load save a File

Post by dodicat »

That's the way to do it.
For wide strings (unicode) then use crt.bi
I hope the Greek translation is correct!

Code: Select all


#include "crt.bi"

type widestring as wstring * 10000

Function filelength(filename As wstring Ptr)As Long
      Dim As wstring * 4 k="r"
      Var fp=_wfopen(filename,@k)
      If fp = 0 Then Print "Error opening file":Sleep:End
      fseek(fp, 0, SEEK_END)
      Var length=ftell(fp)
      fclose(fp)
      Return(length)
End Function

Sub savefile overload(content As String ,filename As wstring Ptr)
      Dim As wstring * 4 k="wb"
      Var fp= _wfopen(filename,@k)
      If fp = 0 Then Print "Error opening file":Sleep:End
      fwrite(@content[0], 1, Len(content), fp)
      fclose(fp)
End Sub

Sub loadfile overload( content As String,filename As wString Ptr)
      Var l=Filelength(filename)
      content=String(l,0)
      Dim As wstring * 4 k="rb"
      Var fp= _wfopen(filename,@k)
      If fp = 0 Then Print "Error loading file ";filename:Sleep:End
      fread(@content[0], 1,l, fp)
      fclose(fp)
End Sub

Sub savefile(content As wString ,filename As wstring Ptr)
      Dim As wstring * 4 k="wb"
      Var fp= _wfopen(filename,@k)
      If fp = 0 Then Print "Error opening file":Sleep:End
      fwrite(@content[0], 2, Len(content), fp)
      fclose(fp)
End Sub

Sub loadfile(content As wString,filename As wString Ptr)
      Var l=Filelength(filename)
      content=wString(l,0)
      Dim As wstring * 4 k="rb"
      Var fp= _wfopen(filename,@k)
      If fp = 0 Then Print "Error loading file ";filename:Sleep:End
      fread(@content[0], 2,l, fp)
      fclose(fp)
End Sub

Function exists(filename As wString Ptr) As boolean
      Dim As wstring * 4 k="r"
      Var fp= _wfopen(filename,@k)
      If fp=0 Then
            Return false
      Else
            fclose(fp)
            Return true
      End If
End Function

dim as wstring * 200 txt=wchr(915,949,953,940,32,963,959,965,32,954,972,963,956,959,962)
                    txt+=wchr(32,45,45,32,105,115,32,103,114,101,101,107,32,102,111,114,32,104,101,108,108,111,32,119,111,114,108,100)

print txt
savefile(txt,"myfile.txt")
dim as widestring contents
loadfile(contents,"myfile.txt")
print "from file"
print contents
print "Length of file "; filelength("myfile.txt")
sleep
kill "myfile.txt"
if exists("myfile.txt") then print "Please delete file" else print "deleted" 
sleep
 

 
Last edited by dodicat on May 21, 2025 9:32, edited 1 time in total.
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Test load save a File

Post by Löwenherz »

Thank you dodicat one more good example.
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Test load save a File

Post by fxm »

Note:
- Naturally, Get#/Put# is used with Binary/Random Access file mode, and [Line] Input#/Input()/Write#/Print# with Input/Output/Append Access file mode.
- However, I have already noticed that Binary/Random Access file mode is also allowed with [Line] Input#/Input()/Write#/Print#.
- This is not currently a FreeBASIC requirement (it is not explicitly mentioned in the documentation), and therefore we can not guarantee that it will still be true for future versions of fbc.
- However, this feature also works in Quick Basic, so it is not a new feature introduced in FreeBASIC.
- Similarly, Get#/Put# can be used with Input/Output/Append Access file mode.

@Jeff,
- Will Binary/Random Access file mode remain allowed with [Line] Input#/Input()/Write#/Print#, and will Input/Output/Append Access file mode remain allowed with Get#/Put# ?
- If so, should this be added to the FreeBASIC documentation (as a simple note I propose, without precise description or example) ?
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Test load save a File

Post by dodicat »

Hi Löwenherz
I have given type widestring some body, the results do not interfere with memory, they are safe if the size of widestring can at least hold the content of a loaded file.
fxm
put and get a string in binary make human readable files and are saved and loaded thus.
This has been my observation so far in fb.
arrays() and utd's and udt arrays can be block loaded and saved with get and put, but the files are not human readable.

Code: Select all

#include "file.bi"

Sub save(filename As String,d() As double)
    Dim As Integer n
    n=Freefile
    If Open (filename For Binary Access Write As #n)=0 Then
        Put #n,,d()
        Close
    Else
        Print "Unable to save " + filename
    End If
End Sub

sub load(file as string,d() as double)
   var  f=freefile
   if Open (file For Binary Access Read As #f)=0 then
    If Lof(f) > 0 Then
      Get #f, ,d()
    End If
    Close #f
else
   Print "Unable to load " + file
    End If  
end sub

dim as string myfile="Mydoubles.txt"

const pi=4*atn(1)
dim as double d(1 to ...)={1.1,2.2,3.3,2*pi}
save myfile,d()

dim as long L=filelen(myfile)/sizeof(double)
dim as double e(1 to L)

load myfile,e()

for n as long=1 to L
    print e(n);" ";
next
print

shell "notepad Mydoubles.txt"
kill myfile
 
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Test load save a File

Post by fxm »

Regardless of the file access mode and the input/output keywords used, strings are always stored as sequences of ASCII codes (bytes), therefore directly readable by any text editor.
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Test load save a File

Post by dodicat »

I think binary is probably the only sure way to load a string from text, input and line input have some serious flaws.

Code: Select all


Enum
    _lineinput
    _input
    _binary
End Enum

Sub savefile(filename As String,p As String)
    Dim As Integer n
    n=Freefile
    If Open (filename For Binary Access Write As #n)=0 Then
        Put #n,,p
        Close
    Else
        Print "Unable to save " + filename
    End If
End Sub


Function load(file As String,flag As Integer) As String
    Dim As Long  f=Freefile
    If flag=0 Or flag=1 Then Open file For Input As #f 
    If flag=2 Then Open file For Binary Access Read As #f
    Dim As String text
    If Lof(f) > 0 Then
        If flag=0 Then Line Input #f, text
        If flag=1 Then Input #f, text
        If flag=2 Then text = String(Lof(f), 0): Get #f, , text
        Close #f
    Else
        Return "error"
    End If
    Return text
End Function

Dim As String s="A"+Chr(0)+"FreeBASIC file access mode"+Chr(10)+"test."+Chr(13,10)+"Goodbye"
savefile "silly.txt",s
Print "string:"
Print
Print s
Print
Print
Print load("silly.txt",_lineinput);Tab(50);"line input"
Print
Print
Print load("silly.txt",_input);Tab(50);"input"
Print
Print
Print load("silly.txt",_binary);Tab(50);"binary"
Sleep

Kill "silly.txt"
 
fxm
Moderator
Posts: 12576
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Test load save a File

Post by fxm »

Specifically, it is Put#/Get#, used with Binary/Random file mode or even Input/Output/Append file mode, that allows for more faithful and flexible retrieval of any recorded string or part of a string.
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Test load save a File

Post by Löwenherz »

Hello dodicat.. thanks for your examples and also fxm ..

@dodicat: in your example with shell "notepad Mydoubles.txt" the Output in Notepad editor is wrong.. the console Output is OK.
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Test load save a File

Post by dodicat »

Hi Löwenherz
The file is binary.
Here is the crt way.

Code: Select all


#include "crt.bi"

Function filelength(filename As wstring Ptr)As Long
      Dim As wstring * 4 k="r"
      Var fp=_wfopen(filename,@k)
      If fp = 0 Then Print "Error opening file":Sleep:End
      fseek(fp, 0, SEEK_END)
      Var length=ftell(fp)
      fclose(fp)
      Return(length)
End Function

Sub savefile overload(content() As double ,filename As wstring Ptr)
      Dim As wstring * 4 k="wb"
      Var fp= _wfopen(filename,@k)
      If fp = 0 Then Print "Error opening file":Sleep:End
      fwrite(@content(lbound(content)), 1, (ubound(content)-lbound(content)+1)*sizeof(double), fp)
      fclose(fp)
End Sub

Sub loadfile overload( content() As double,filename As wString Ptr)
      Var l=Filelength(filename)
      redim content(1 to l/sizeof(double))
      Dim As wstring * 4 k="rb"
      Var fp= _wfopen(filename,@k)
      If fp = 0 Then Print "Error loading file ";filename:Sleep:End
      fread(@content(lbound(content)), 1,l, fp)
      fclose(fp)
End Sub

Function exists(filename As wString Ptr) As boolean
      Dim As wstring * 4 k="r"
      Var fp= _wfopen(filename,@k)
      If fp=0 Then
            Return false
      Else
            fclose(fp)
            Return true
      End If
End Function

dim as string myfile="Mydoubles.txt"

const pi=4*atn(1)
dim as double d(1 to ...)={1.1,2.2,3.3,2*pi}
savefile d(),myfile

dim as double e()

loadfile e(),myfile

for n as long=lbound(e) to ubound(e)
    print e(n);" ";
next
print

shell "notepad Mydoubles.txt"
kill myfile
print exists(myfile)
print "done"
sleep
 

 
Which produces a similar binary file, which goes to show that put and get in fb are directly from the c runtime (msvcrt.dll) which is always loaded in windows by fbc.
Löwenherz
Posts: 277
Joined: Aug 27, 2008 6:26
Location: Bad Sooden-Allendorf, Germany

Re: Test load save a File

Post by Löwenherz »

Hello dodicat .. I did this example just for fun to Display the Word Hello to greek language
Thanks for your last example..

Code: Select all

' I am using here WinFBE editor for displaying the greek character in editor
' you must change ANSI to UTF-8 (BOM) first
#define UNICODE
#if defined( __FB_WIN32__ )
#include "windows.bi" ' only for messagebox
#endif

dim a as wstring * 16
a = "Καλημέρα" ' greek character translated to "Hello" 
print asc( a )  ' 922
print a 
MessageBox(null, a, "greek hello",MB_OK Or MB_ICONINFORMATION)
sleep

' output console ok and messagebox shows greek characters ok too
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Test load save a File

Post by dodicat »

Thanks Löwenherz .
I had to put a utf bom at the head of a file

Code: Select all

 
to get

Code: Select all

922
Καλημέρα
 
The message box showed up OK also.
dodicat
Posts: 8267
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Test load save a File

Post by dodicat »

This should work in fbide(bom added):

Code: Select all


' I am using here WinFBE editor for displaying the greek character in editor
' you must change ANSI to UTF-8 (BOM) first
#define UNICODE
#if defined( __FB_WIN32__ )
#include "windows.bi" ' only for messagebox
#endif

dim a as wstring * 16
a = "Καλημέρα" ' greek character translated to "Hello" 
print asc( a )  ' 922
print a 
MessageBox(null, a, "greek hello",MB_OK Or MB_ICONINFORMATION)
sleep

' output console ok and messagebox shows greek characters ok too 
coderJeff
Site Admin
Posts: 4386
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Test load save a File

Post by coderJeff »

fxm wrote: May 20, 2025 12:03 @Jeff,
- Will Binary/Random Access file mode remain allowed with [Line] Input#/Input()/Write#/Print#, and will Input/Output/Append Access file mode remain allowed with Get#/Put# ?
- If so, should this be added to the FreeBASIC documentation (as a simple note I propose, without precise description or example) ?
Even in qb days, one would not typically mix all file modes with all read/write methods interchangeably. I would guess that full qb compatibility was not a goal with regards to fully mixing everything together when fb runtime library was being first written.

My opinion?
- should indicate which modes and methods are intended to work together. get/put with binary/random; line input/input/write/print with input/output/append. That's how I use them, and that probably how it was in the minds of first fbc developers. And if those minimal combinations don't work together as expected, then that it is a bug.
- provide a note that intermixing modes and methods was never well tested and results may vary
- optionally document how it works now. That may give some future developer a starting point for what might be improved (for example line input on random access file: should this check for CR or CR+LF or LF, or read to end of record, cross platform differences, etc).
angros47
Posts: 2409
Joined: Jun 21, 2005 19:04

Re: Test load save a File

Post by angros47 »

I remember discussing it some years ago:
https://www.freebasic.net/forum/viewtopic.php?t=27765

I actually used mixed mode to read WAV files , since I wanted to put some binary data into a string, I found out that under Linux it was possible to access a binary file with "open for input", under Windows it had some issues, because of Windows changing CR to CR/LF, if I recall. By using "open for binary access read/write" the issue was solved. For me, using mixed mode is useful, and I hope it won't be removed in future versions. Seeing how things work under the hood, I see no reason for not supporting it in future versions. So, I hope it will be considered a standard feature.
Post Reply