DAY 037: FREEFILE
#1
We interrupt your regularly scheduled program for this brief commercial message!

Tired of spending your hard earned money on an overly-priced file? Well now you can avoid those high fees with this tried and true QB Keyword of the Day, FREEFILE!

SYNTAX filenum& = FREEFILE

Usage: Retrieves the next available open file handle.

So what's the benefit?

Well, for most small apps, we just code...

Code: (Select All)
OPEN "myfile.dat" FOR INPUT AS #1
'De Foo Foo Foo De blah, blah, blah...
CLOSE #1

However, let's say we make a big app, that uses 30 files, and some of them, depending on operations being called, stay opened!

Hmm, now keeping track of all those file numbers would require considerable thought. In fact, the only way to not to get into trouble, by using a file number which is still opened, would be to assign a unique number to each file operation, or... do it the easy way by letting the system figure it out for us. Well, that's exactly what FREEFILE does!

But first, please note: Even though we can assign a variable to FREEFILE before we OPEN the file, "You actually have to Open the file to trigger a value." Thanks, Dimster. So
please make sure you use good coding practice and associate each FREEFILE statement with each corresponding OPEN statement.

Code: (Select All)
DEFLNG f
ON Rob GOSUB ThePolice

ThePolice:
filenum1 = FREEFILE
OPEN "myfile-abc.dat" FOR INPUT AS filenum1
'De Foo Foo Foo De blah, blah, blah...

filenum2 = FREEFILE
OPEN "myfile-def.dat" FOR INPUT AS filenum2
'Is all I will output to you...

IF mydata$ = "EOF" THEN CLOSE #filenum1

filenum3 = FREEFILE
OPEN "myfile-ghi.dat" FOR INPUT AS filenum3
'De Foo Foo Foo De blah, blah, blah...

filenum4 = FREEFILE
OPEN "myfile-jkl.dat" FOR INPUT AS filenum4
' And now this FREEFILE demo's through.
CLOSE #filenum1, #filenum2, #filenum3, #filenum4
RETURN

So in the code example above, FREEFILE will assign the file handles either as 1, 2, 3, and 4 or, if mydata$ = "EOF" and the first file gets closed... 1, 2, 1, 3. Remember, FREEFILE is tracking your file use, and depending on conditional statements, like in our above example, your file numbering results will vary. Also, always remember to use good coding practices. Don't have a list of pre-assigned FREEFILE assignments, at the top of your program, without each corresponding file actually being opened. You will get duplicate file handles.

Oh, and if you forget to add the # symbol, don't worry; it's optional. I just like using it as a search marker. What;s that? You don't need no stinkin' search marker. Alrighty then, save yourself some typing by omitting it. Like I always say to my wife, "It takes a big man to omit when he's wrong!" Okay Steve, enough with the "big man" jokes, already...

And now back to your regularly scheduled program, DEEP Thoughts, by jack handy...

Do woke coders OPEN files as non-BINARY?

Pete
Reply
#2
This is an important function, because otherwise we would have to memorize much more than credit card, social security, PIN, passwords and much more that came with the weight of civilization.

It's shocking that "FREEFILE" was rarely, if ever, used in the earliest BASIC code presented by Galleon. I think I saw a "#26" somewhere as file handle. Several variables were being allocated, each one was megabytes in size, but too much trouble to create at least an array of 40 long-integer file handles? Too much typing instead.

"FREEFILE" is one function that was necessary to keep BASIC in pace with C and other languages where the programmer has to refer to a "handle" stored in a variable. In some languages like Lua that variable cannot be an integer. Imagine if we still had to do "PRINT #26" or alike but for images, music and windows. "No you may not use &HDEADBEEF as file handle!"

However, a few languages like Purebasic opted to create single functions combining the functionality of "FREEFILE" and "OPEN", such as "CreateFile", "AppendFile" and "OpenFile" (this last one is to open for input only). Probably it's called "ReadFile", while "OpenFile" is to be used for non-sequential files in either mode.
Reply
#3
I store data in files with similar Names, I just tag on a number at the end to separate them. I then use a routine which will open multiple files. For example, 

FileName$ = "DataDAY"
For FNum = 1 To 31
    FN$ = Str$(FNum)
    Print FileName$ + LTrim$(FN$) ' NOTE: Using "Print" here to show the actual File Name generated
    'open FileName$+LTrim$(FN$) as #FNum
Next FNum
Sleep
 I get DataDay1, DataDay2, DataDay3 ...DataDay31

However using FreeFile like this'

For FNum = 1 To 31
    FN = FreeFile
    FN$ = Str$(FN) 'Str$(FNum)???
    Print FileName$ + LTrim$(FN$)
    'open FileName$+LTrim$(FN$) as ???
Next FNum


I get DataDay1, DataDay1, DataDay1...DataDay1

To open multiple files with FreeFile, I tried this method


Day1 = FreeFile
Day1$ = Str$(Day1)
Print FileName$ + LTrim$(Day1$)

DataDay2 = FreeFile
Day2$ = Str$(Day2)
Print FileName$ + LTrim$(Day2$)


DataDay3 = FreeFile
Day3$ = Str$(Day3)
Print FileName$ + LTrim$(Day3$)


This gives me   DataDay1, DataDay0, DataDay0

Opening multiple files using FreeFile is alluding me.
Reply
#4
After getting a value from "FREEFILE" you have to actually open a file successfully. Otherwise it will return the same value. In your code you commented out the "OPEN" statement and that's why it's not working.

Also never begin a variable name with "FN" because it's legacy part of "DEF FN". Instead of "AS ???" most of all you should use the long-integer variable return value from "FREEFILE" in the "OPEN" statement.
Reply
#5
@Dimster All FREEFILE does is give you the next available file handle.  That's it, in a nutshell.  Nothing more, nothing less.

So let's say the next available file handle is 1.

x = FREEFILE   <-- it's 1.
y = FREEFILE  <-- it's still 1.  Sure, we reported that handle to X, but we haven't used it yet.  It's still available.
z = FREEFILE  <-- it's still 1.  Sure, we reported that handle to X and Y, but we haven't used it yet.  It's still available.

OPEN "temp.txt" FOR BINARY AS #x  <-- Now here, we used that file handle #1 (x = 1, after all).

OPEN "temp2.txt" FOR BINARY AS #y  <-- This is going to error out.  y is 1, and handle 1 is already opened.  We can't have two files with the same handle opened at the same time!!

a = FREEFILE <-- this is now 2.  File handle 1 is in use with "temp.txt" and X.  2 is now our latest free file handle.
CLOSE x  <-- we just closed "temp.txt" and freed up file handle 1.  (x = 1, after all)
b = FREEFILE  <-- and this is now 1.  File handle 1 has been freed, it's available for use again, so we recycle it back to b.



So, if you followed that, you can see -- all FREEFILE does is give us the next available file handle.  Until you use the handle it gives you, it's still available.  

The way you'd use it with your code would be:

DataDay1 = FreeFile
Day1$ = Str$(Day1)
Open FileName$+LTrim$(Day1$) as #DataDay1

DataDay2 = FreeFile
Day2$ = Str$(Day2)
Open FileName$+LTrim$(Day2$) as #DataDay2
Reply
#6
OH, I hadn't realize you actually have to Open the file to trigger a value.
Reply
#7
Well @Dimster , if you bothered to read my thread...

>Now folks, please make sure you use good coding practice and associate each FREEFILE statement with each corresponding OPEN statement. In other words don't have a list of pre-assigned FREEFILE assignments at the top of your program or you might get duplicate file handles. Remember, FREEFILE is tracking your file use, and depending on conditional statements, like in our example, your results may vary.

Of course, you'd be divorced by doing so, so I get it...

Anyway, just kidding. My fault, I should have figured a way to make it much more clearer...

Hmm, what to do... Oh I know, I'll go back and edit it be be something more profound like "You actually have to Open the file to trigger a value." Wow, where do I come up withe these! Big Grin

Thanks,

Pete
Reply
#8
Ya Pete - things not good for the marriage includes NOT reading instructions - it's a male know-it-all thing. In my defense I thought the assignment statement held the File # value (ie DataDay1 = FreeFile) as opposed to the Open statement. If it was the assignment statement then the Print command should have displayed exactly what I would have gotten with the Open command which I had commented out. Anyway, oh protector of the pearly gates, I am a little more of a know-it-all with these non-common commands.
Reply
#9
Actually, you're perfect. A lot of folks won't discuss things for fear someone else will know what they don't, and tell them so. I'm a bit different. I just run and gun, and don't really react when that happens to me. I'd rather learn something than protect my ego. Hey wait, that means I'm perfect too. I knew there was a point to make here, it just took awhile to get to it. Big Grin

Actually, I've relied on this keyword for as long as I can remember, having done extensive work with multiple files. Your post made me realize this is either one of the few, or perhaps the only, QBasic keyword that requires an event to occur after it is assigned to a variable to assign the next incremental value to it. Pretty cool!

Pete
Reply




Users browsing this thread: 3 Guest(s)