<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="VB6Parse Library Reference - freefile - File">
<title>freefile - File - VB6Parse Library Reference</title>
<link rel="stylesheet" href="../../../assets/css/style.css">
<link rel="stylesheet" href="../../../assets/css/docs-style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
<script src="../../../assets/js/theme-switcher.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/vbnet.min.js"></script>
<script>hljs.highlightAll();</script>
</head>
<body>
<header class="docs-header">
<div class="container">
<h1><a href="../../../index.html">VB6Parse</a> / <a href="../../../library/index.html">Library</a> / <a href="../../../library/functions/file/index.html">File</a> / freefile</h1>
<p class="tagline">VB6 Library Reference</p>
</div>
</header>
<nav class="docs-nav">
<div class="container">
<a href="../../../index.html">Home</a>
<a href="../../../library/index.html">Library Reference</a>
<a href="../../../documentation.html">Documentation</a>
<a href="https://docs.rs/vb6parse" target="_blank">API Docs</a>
<a href="https://github.com/scriptandcompile/vb6parse" target="_blank">GitHub</a>
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme">
<span class="theme-icon">🌙</span>
</button>
</div>
</nav>
<main class="container">
<article class="library-item">
<p>FreeFile Function
Returns an <code>Integer</code> representing the next file number available for use by the Open statement.</p>
<h1 id="syntax">Syntax</h1>
<pre><code class="language-vbnet">FreeFile[(rangenumber)]</code></pre>
<h1 id="parameters">Parameters</h1>
<ul>
<li><code>rangenumber</code> - Optional. Variant that specifies which range of file numbers to use.</li>
<li><code>0</code> (default) - Returns a file number in the range 1-255 (inclusive).</li>
<li><code>1</code> - Returns a file number in the range 256-511 (inclusive).</li>
</ul>
<h1 id="return-value">Return Value</h1>
<p>Returns an <code>Integer</code> representing the next available file number that is not already in use.</p>
<h1 id="remarks">Remarks</h1>
<ul>
<li>Use <code>FreeFile</code> to obtain a file number that is not already associated with an open file.</li>
<li><code>FreeFile</code> returns the lowest available file number in the specified range.</li>
<li>When using multiple files, always use <code>FreeFile</code> to avoid conflicts with file numbers.</li>
<li>The file number returned can be used with the <code>Open</code> statement to open a file.</li>
<li>After obtaining a file number with <code>FreeFile</code>, use it immediately to avoid conflicts.</li>
<li>File numbers are released when the file is closed with the <code>Close</code> statement.</li>
<li>The function is particularly important in libraries and reusable code where you don't know what file numbers are already in use.</li>
</ul>
<h1 id="typical-uses">Typical Uses</h1>
<ul>
<li>Opening files for sequential, random, or binary access</li>
<li>Writing to log files</li>
<li>Reading configuration files</li>
<li>Temporary file operations</li>
<li>Data import/export operations</li>
<li>File-based data storage</li>
</ul>
<h1 id="basic-usage-examples">Basic Usage Examples</h1>
<pre><code class="language-vbnet">' Basic file operations
Dim fileNum As Integer
fileNum = FreeFile
Open "data.txt" For Output As #fileNum
Print #fileNum, "Hello, World!"
Close #fileNum
' Multiple file operations
Dim inputFile As Integer
Dim outputFile As Integer
inputFile = FreeFile
Open "input.txt" For Input As #inputFile
outputFile = FreeFile
Open "output.txt" For Output As #outputFile
' Process files...
Close #inputFile
Close #outputFile
' Using range parameter
Dim highRangeFile As Integer
highRangeFile = FreeFile(1) ' Returns 256-511
Open "temp.dat" For Binary As #highRangeFile
Close #highRangeFile
' Immediate use pattern
Open "log.txt" For Append As #FreeFile
' Note: Cannot close without saving the file number</code></pre>
<h1 id="common-patterns">Common Patterns</h1>
<h2 id="1-simple-file-read">1. Simple File Read</h2>
<pre><code class="language-vbnet">Sub ReadTextFile(filename As String)
Dim fileNum As Integer
Dim line As String
fileNum = FreeFile
Open filename For Input As #fileNum
Do While Not EOF(fileNum)
Line Input #fileNum, line
Debug.Print line
Loop
Close #fileNum
End Sub</code></pre>
<h2 id="2-simple-file-write">2. Simple File Write</h2>
<pre><code class="language-vbnet">Sub WriteTextFile(filename As String, content As String)
Dim fileNum As Integer
fileNum = FreeFile
Open filename For Output As #fileNum
Print #fileNum, content
Close #fileNum
End Sub</code></pre>
<h2 id="3-append-to-log-file">3. Append to Log File</h2>
<pre><code class="language-vbnet">Sub LogMessage(message As String)
Dim fileNum As Integer
fileNum = FreeFile
Open App.Path & "\app.log" For Append As #fileNum
Print #fileNum, Now & " - " & message
Close #fileNum
End Sub</code></pre>
<h2 id="4-copy-file-contents">4. Copy File Contents</h2>
<pre><code class="language-vbnet">Sub CopyFile(source As String, destination As String)
Dim sourceNum As Integer
Dim destNum As Integer
Dim line As String
sourceNum = FreeFile
Open source For Input As #sourceNum
destNum = FreeFile
Open destination For Output As #destNum
Do While Not EOF(sourceNum)
Line Input #sourceNum, line
Print #destNum, line
Loop
Close #sourceNum
Close #destNum
End Sub</code></pre>
<h2 id="5-read-binary-file">5. Read Binary File</h2>
<pre><code class="language-vbnet">Function ReadBinaryFile(filename As String) As Byte()
Dim fileNum As Integer
Dim fileSize As Long
Dim buffer() As Byte
fileNum = FreeFile
Open filename For Binary As #fileNum
fileSize = LOF(fileNum)
ReDim buffer(0 To fileSize - 1)
Get #fileNum, , buffer
Close #fileNum
ReadBinaryFile = buffer
End Function</code></pre>
<h2 id="6-write-binary-file">6. Write Binary File</h2>
<pre><code class="language-vbnet">Sub WriteBinaryFile(filename As String, data() As Byte)
Dim fileNum As Integer
fileNum = FreeFile
Open filename For Binary As #fileNum
Put #fileNum, , data
Close #fileNum
End Sub</code></pre>
<h2 id="7-read-ini-style-configuration">7. Read INI-Style Configuration</h2>
<pre><code class="language-vbnet">Function ReadConfigValue(filename As String, key As String) As String
Dim fileNum As Integer
Dim line As String
Dim pos As Integer
fileNum = FreeFile
Open filename For Input As #fileNum
Do While Not EOF(fileNum)
Line Input #fileNum, line
line = Trim(line)
If Left(line, Len(key) + 1) = key & "=" Then
ReadConfigValue = Mid(line, Len(key) + 2)
Close #fileNum
Exit Function
End If
Loop
Close #fileNum
ReadConfigValue = ""
End Function</code></pre>
<h2 id="8-write-csv-file">8. Write CSV File</h2>
<pre><code class="language-vbnet">Sub WriteCSV(filename As String, data() As Variant)
Dim fileNum As Integer
Dim i As Long, j As Long
Dim row As String
fileNum = FreeFile
Open filename For Output As #fileNum
For i = LBound(data, 1) To UBound(data, 1)
row = ""
For j = LBound(data, 2) To UBound(data, 2)
If j > LBound(data, 2) Then row = row & ","
row = row & CStr(data(i, j))
Next j
Print #fileNum, row
Next i
Close #fileNum
End Sub</code></pre>
<h2 id="9-read-entire-file-into-string">9. Read Entire File into String</h2>
<pre><code class="language-vbnet">Function ReadFileAsString(filename As String) As String
Dim fileNum As Integer
Dim fileContent As String
fileNum = FreeFile
Open filename For Input As #fileNum
fileContent = Input(LOF(fileNum), fileNum)
Close #fileNum
ReadFileAsString = fileContent
End Function</code></pre>
<h2 id="10-process-large-file-line-by-line">10. Process Large File Line by Line</h2>
<pre><code class="language-vbnet">Sub ProcessLargeFile(filename As String)
Dim fileNum As Integer
Dim line As String
Dim lineCount As Long
fileNum = FreeFile
Open filename For Input As #fileNum
lineCount = 0
Do While Not EOF(fileNum)
Line Input #fileNum, line
lineCount = lineCount + 1
' Process line here
If lineCount Mod 1000 = 0 Then
Debug.Print "Processed " & lineCount & " lines..."
End If
Loop
Close #fileNum
Debug.Print "Total lines: " & lineCount
End Sub</code></pre>
<h1 id="advanced-usage">Advanced Usage</h1>
<h2 id="1-file-manager-class">1. File Manager Class</h2>
<pre><code class="language-vbnet">' Class module: FileManager
Private m_FileNumber As Integer
Public Sub OpenFile(filename As String, mode As String)
m_FileNumber = FreeFile
Select Case LCase(mode)
Case "read"
Open filename For Input As #m_FileNumber
Case "write"
Open filename For Output As #m_FileNumber
Case "append"
Open filename For Append As #m_FileNumber
Case "binary"
Open filename For Binary As #m_FileNumber
End Select
End Sub
Public Sub WriteLine(text As String)
Print #m_FileNumber, text
End Sub
Public Function ReadLine() As String
Dim line As String
If Not EOF(m_FileNumber) Then
Line Input #m_FileNumber, line
ReadLine = line
End If
End Function
Public Function IsEOF() As Boolean
IsEOF = EOF(m_FileNumber)
End Function
Public Sub CloseFile()
If m_FileNumber > 0 Then
Close #m_FileNumber
m_FileNumber = 0
End If
End Sub
Private Sub Class_Terminate()
CloseFile
End Sub</code></pre>
<h2 id="2-safe-file-operations-with-error-handling">2. Safe File Operations with Error Handling</h2>
<pre><code class="language-vbnet">Function SafeWriteFile(filename As String, content As String) As Boolean
Dim fileNum As Integer
On Error GoTo ErrorHandler
fileNum = FreeFile
Open filename For Output As #fileNum
Print #fileNum, content
Close #fileNum
SafeWriteFile = True
Exit Function
ErrorHandler:
If fileNum > 0 Then Close #fileNum
SafeWriteFile = False
Debug.Print "Error writing file: " & Err.Description
End Function</code></pre>
<h2 id="3-multi-file-transaction-manager">3. Multi-File Transaction Manager</h2>
<pre><code class="language-vbnet">Type FileHandle
Number As Integer
Filename As String
IsOpen As Boolean
End Type
Sub TransactionExample()
Dim files(1 To 3) As FileHandle
Dim i As Integer
On Error GoTo Rollback
' Open multiple files
For i = 1 To 3
files(i).Number = FreeFile
files(i).Filename = "file" & i & ".txt"
files(i).IsOpen = False
Next i
' Perform operations
For i = 1 To 3
Open files(i).Filename For Output As #files(i).Number
files(i).IsOpen = True
Print #files(i).Number, "Data for file " & i
Next i
' Success - close all
For i = 1 To 3
Close #files(i).Number
files(i).IsOpen = False
Next i
Exit Sub
Rollback:
' Clean up any open files
For i = 1 To 3
If files(i).IsOpen Then
Close #files(i).Number
End If
Next i
MsgBox "Transaction failed: " & Err.Description
End Sub</code></pre>
<h2 id="4-file-pool-manager">4. File Pool Manager</h2>
<pre><code class="language-vbnet">' Module-level variables
Private m_FilePool() As Integer
Private m_PoolSize As Integer
Sub InitializeFilePool(poolSize As Integer)
Dim i As Integer
m_PoolSize = poolSize
ReDim m_FilePool(1 To poolSize)
For i = 1 To poolSize
m_FilePool(i) = FreeFile(1) ' Use high range
Next i
End Sub
Function GetPooledFileNumber() As Integer
Static currentIndex As Integer
currentIndex = currentIndex + 1
If currentIndex > m_PoolSize Then currentIndex = 1
GetPooledFileNumber = m_FilePool(currentIndex)
End Function</code></pre>
<h2 id="5-buffered-file-writer">5. Buffered File Writer</h2>
<pre><code class="language-vbnet">Type BufferedWriter
FileNumber As Integer
Buffer As String
BufferSize As Long
MaxBufferSize As Long
End Type
Sub InitBufferedWriter(writer As BufferedWriter, filename As String, _
Optional maxBuffer As Long = 4096)
writer.FileNumber = FreeFile
writer.MaxBufferSize = maxBuffer
writer.BufferSize = 0
writer.Buffer = ""
Open filename For Output As #writer.FileNumber
End Sub
Sub BufferedWrite(writer As BufferedWriter, text As String)
writer.Buffer = writer.Buffer & text & vbCrLf
writer.BufferSize = Len(writer.Buffer)
If writer.BufferSize >= writer.MaxBufferSize Then
Print #writer.FileNumber, writer.Buffer;
writer.Buffer = ""
writer.BufferSize = 0
End If
End Sub
Sub FlushBufferedWriter(writer As BufferedWriter)
If writer.BufferSize > 0 Then
Print #writer.FileNumber, writer.Buffer;
writer.Buffer = ""
writer.BufferSize = 0
End If
Close #writer.FileNumber
End Sub</code></pre>
<h2 id="6-temporary-file-manager">6. Temporary File Manager</h2>
<pre><code class="language-vbnet">Function CreateTempFile() As Integer
Dim fileNum As Integer
Dim tempPath As String
Dim tempFile As String
tempPath = Environ("TEMP")
If Right(tempPath, 1) <> "\" Then tempPath = tempPath & "\"
tempFile = tempPath & "temp_" & Format(Now, "yyyymmddhhnnss") & ".tmp"
fileNum = FreeFile
Open tempFile For Binary As #fileNum
CreateTempFile = fileNum
End Function
Sub DeleteTempFile(fileNum As Integer)
Dim filename As String
' Get filename before closing
filename = FileAttr(fileNum, 1) ' Returns filename
Close #fileNum
Kill filename ' Delete the file
End Sub</code></pre>
<h1 id="error-handling">Error Handling</h1>
<pre><code class="language-vbnet">Function SafeFileOperation(filename As String) As Boolean
Dim fileNum As Integer
On Error GoTo ErrorHandler
fileNum = FreeFile
Open filename For Input As #fileNum
' Process file...
Close #fileNum
SafeFileOperation = True
Exit Function
ErrorHandler:
' Always try to close the file
On Error Resume Next
If fileNum > 0 Then Close #fileNum
On Error GoTo 0
Select Case Err.Number
Case 53 ' File not found
Debug.Print "File not found: " & filename
Case 55 ' File already open
Debug.Print "File already open: " & filename
Case 70 ' Permission denied
Debug.Print "Permission denied: " & filename
Case 71 ' Disk not ready
Debug.Print "Disk not ready"
Case 76 ' Path not found
Debug.Print "Path not found: " & filename
Case Else
Debug.Print "Error " & Err.Number & ": " & Err.Description
End Select
SafeFileOperation = False
End Function</code></pre>
<p>Common errors:
- <strong>Error 55 (File already open)</strong>: File number is already in use. Always use <code>FreeFile</code> to avoid this.
- <strong>Error 52 (Bad file name or number)</strong>: Invalid file number. Ensure the number is in the valid range.
- <strong>Error 53 (File not found)</strong>: The specified file does not exist.
- <strong>Error 76 (Path not found)</strong>: The specified path does not exist.</p>
<h1 id="performance-considerations">Performance Considerations</h1>
<ul>
<li><code>FreeFile</code> is a very fast operation - no overhead in calling it</li>
<li>Always store the result in a variable for later use with <code>Close</code></li>
<li>Don't call <code>FreeFile</code> repeatedly in tight loops - get the number once and reuse it</li>
<li>Consider using the high range (256-511) for system or library files to avoid conflicts with user code</li>
<li>File operations themselves (<code>Open</code>, <code>Close</code>, <code>Read</code>, <code>Write</code>) are much slower than <code>FreeFile</code></li>
</ul>
<h1 id="best-practices">Best Practices</h1>
<ol>
<li><strong>Always use <code>FreeFile</code></strong> instead of hard-coding file numbers</li>
<li><strong>Store the file number</strong> in a variable so you can close the file later</li>
<li><strong>Close files promptly</strong> when done to release the file number</li>
<li><strong>Use error handling</strong> to ensure files are closed even if an error occurs</li>
<li><strong>Use high range (1)</strong> for system/library code to avoid conflicts</li>
<li><strong>Open and close files in pairs</strong> - every <code>Open</code> should have a corresponding <code>Close</code></li>
<li><strong>Don't assume file numbers</strong> - always get a fresh number with <code>FreeFile</code></li>
</ol>
<h1 id="comparison-with-other-approaches">Comparison with Other Approaches</h1>
<h2 id="freefile-vs-hard-coded-numbers"><code>FreeFile</code> vs Hard-Coded Numbers</h2>
<pre><code class="language-vbnet">' Bad - Hard-coded file number
Open "data.txt" For Input As #1
' What if file #1 is already open?
' Good - Use FreeFile
Dim fileNum As Integer
fileNum = FreeFile
Open "data.txt" For Input As #fileNum</code></pre>
<h2 id="freefile-vs-filesystemobject"><code>FreeFile</code> vs <code>FileSystemObject</code></h2>
<pre><code class="language-vbnet">' FreeFile approach - built-in, fast, simple
Dim fileNum As Integer
fileNum = FreeFile
Open "data.txt" For Input As #fileNum
' ...
Close #fileNum
' FileSystemObject - more features, requires reference
Dim fso As New FileSystemObject
Dim ts As TextStream
Set ts = fso.OpenTextFile("data.txt", ForReading)
' ...
ts.Close
Set ts = Nothing
Set fso = Nothing</code></pre>
<h1 id="limitations">Limitations</h1>
<ul>
<li>Maximum of 255 files in the default range (1-255)</li>
<li>Maximum of 256 files in the high range (256-511)</li>
<li>Total maximum of 511 files open simultaneously</li>
<li>File numbers are process-specific (not thread-safe in modern contexts)</li>
<li>No built-in file locking mechanism</li>
<li>Traditional file I/O is slower than modern streaming APIs</li>
</ul>
<h1 id="range-selection">Range Selection</h1>
<p>When to use different ranges:
- <strong>Range 0 (1-255)</strong>: Default for application code, user files
- <strong>Range 1 (256-511)</strong>: System files, library code, background operations</p>
<pre><code class="language-vbnet">' Application uses default range
Dim userFile As Integer
userFile = FreeFile(0) ' or just FreeFile
' Library uses high range to avoid conflicts
Dim sysFile As Integer
sysFile = FreeFile(1)</code></pre>
<h1 id="related-functions">Related Functions</h1>
<ul>
<li><code>Open</code> - Opens a file for reading or writing</li>
<li><code>Close</code> - Closes an open file</li>
<li><code>EOF</code> - Tests for end-of-file</li>
<li><code>LOF</code> - Returns the length of an open file</li>
<li><code>FileAttr</code> - Returns file mode or file handle</li>
<li><code>Seek</code> - Sets or returns the current file position</li>
<li><code>Input</code> - Reads data from a sequential file</li>
<li><code>Print</code> - Writes data to a sequential file</li>
<li><code>Get</code> - Reads data from a binary or random file</li>
<li><code>Put</code> - Writes data to a binary or random file</li>
</ul>
</article>
<div style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border-color);">
<p>
<a href="index.html">← Back to File</a> |
<a href="../index.html">View all functions</a>
</p>
</div>
</main>
<footer>
<div class="container">
<p>© 2024-2026 VB6Parse Contributors. Licensed under the MIT License.</p>
</div>
</footer>
</body>
</html>