I'm working in some C# code that had earlier been converted over from VB6 and it does lots of file I-O. All over the place I see this:
fn = VBNET.FileSystem.FreeFile();
...followed by VBNET.FileSystem.FileOpen(), some file I-O, and then VBNET.FileSystem.FileClose() .
The call to FreeFile() generates a "file number", which is required to open the file. But what IS a file number and how do you release it back to the system when you're done with it?
The documentation at http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.filesystem.freefile.aspx doesn't seem to say, but it does say that an exception would be thrown if "more than 255 files are in use", which implies to me that it would be a good idea to release them when I'm done with them.
N.B. - I understand that there are better file-IO libraries to use but this is what we're stuck with until we have resources to rewrite this stuff, so I just want to understand it.
Those VB6 commands (FreeFile, FileOpen, FileClose, LOF, etc.) were present at least as far back as QBasic. I expect that the file number was originally an MS-DOS file handle.
A quick google search came up with these links:
Back in QBasic (if memory serves), the FileOpen
command opened the file and reserved the file handle. The FileClose
command closed the file and freed the handle.
FreeFile
was just a convenience method to get an unused file handle: if you knew that you didn't have (for example) file #1 open, then you could just call OPEN "C:\DOS\RUN" FOR INPUT AS #1
and not bother calling FreeFile
. You would still close it with CLOSE #1
I can't remember if that changed in VB6. As Hans Passant mentioned, internally in .NET the file number is now just an index into an array of VB6File objects. FileSystem.vb
In early version of BASIC, pre-objects, when you wanted to do I/O to a file, you needed to tell the interpreter which open file you wanted to use by its number. The runtime had a table of open files, and the file number was basically an index into that table. The concept is similar to a file handle, as you would have used via the Windows API, but every BASIC program had it own set of file numbers.
Normally, the way you would do file I/O would be something like the following:
OPEN #1, "path\to\file"
PRINT #1, "Stuff I want in the file"
CLOSE #1
You would be responsible for keeping tracking of which file numbers you had opened, what files they pointed to, etc.
For simple programs, this isn't a big deal, but when you start to write modular programs, with shared subroutines and external libraries and such, that system becomes unworkable. If you're writing a logging routine, for example, you have to somehow select a file number for your log file that you can guarantee is never being used anywhere else, or bad things would happen.
The FreeFile
function is VB's answer to this problem. Calling FreeFile
returns the next available slot in the open files list, which you can then be sure no one else is using. In pseudo-code, it would be like doing this in the above code:
I = 0
WHILE ALREADYOPEN(#I)
I = I + 1
WEND
OPEN #I, "path\to\file"
PRINT #I, "stuff to go into file"
CLOSE #I
FreeFile
basically does the equivalent of the the loop, except it already knows which file numbers are used and which aren't so it can just give you an answer. Otherwise, the I/O works exactly the same: once you have your free file number, you open it, read/write to it, and close it again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With