Working with Files
Prerequisites: Exception handling
File access goes through the System.IO namespace. The File class does
most everyday jobs in one call:
Imports System.IO
Module Program
Sub Main()
File.WriteAllText("notes.txt", "first line" & vbLf & "second line" & vbLf)
File.AppendAllText("notes.txt", "third line" & vbLf)
Console.Write(File.ReadAllText("notes.txt"))
Dim lines = File.ReadAllLines("notes.txt")
Console.WriteLine($"{lines.Length} lines, last: {lines(lines.Length - 1)}")
Console.WriteLine($"{File.Exists("notes.txt")} {File.Exists("missing.txt")}")
End Sub
End Module
first line
second line
third line
3 lines, last: third line
True False
Imports System.IO at the top of the file lets you write File instead
of System.IO.File. Relative paths are relative to the current
directory; AppContext.BaseDirectory gives the folder the program
runs from.
Reading and writing line by line
Imports System.IO
Module Program
Sub Main()
Using writer As New StreamWriter("log.txt")
writer.WriteLine("started")
writer.WriteLine("processing")
writer.WriteLine("finished")
End Using
Using reader As New StreamReader("log.txt")
Dim lineNumber = 0
Do
Dim line = reader.ReadLine()
If line Is Nothing Then Exit Do
lineNumber += 1
Console.WriteLine($"{lineNumber}: {line}")
Loop
End Using
End Sub
End Module
1: started
2: processing
3: finished
Using closes the file even if an exception occurs. For big files,
File.ReadLines(path) (not ReadAllLines) reads lazily, one line at a
time, so it works on files larger than memory.
Processing a CSV file
Imports System.IO
Module Program
Sub Main()
File.WriteAllLines("sales.csv", {
"region,product,amount",
"North,Tea,120",
"South,Coffee,340",
"North,Coffee,90"
})
Dim totals As New Dictionary(Of String, Integer)
For Each line In File.ReadLines("sales.csv").Skip(1)
Dim fields = line.Split(","c)
Dim region = fields(0)
Dim amount = Integer.Parse(fields(2))
totals(region) = If(totals.ContainsKey(region), totals(region), 0) + amount
Next
For Each pair In totals
Console.WriteLine($"{pair.Key}: {pair.Value}")
Next
End Sub
End Module
North: 210
South: 340
Simple Split breaks on quoted fields that contain commas; for real
CSV data, Microsoft.VisualBasic.FileIO.TextFieldParser (built in) or
the CsvHelper package handle quoting correctly.
Directories and paths
Imports System.IO
Module Program
Sub Main()
Directory.CreateDirectory("data/archive")
File.WriteAllText(Path.Combine("data", "a.txt"), "A")
File.WriteAllText(Path.Combine("data", "b.log"), "B")
For Each f In Directory.GetFiles("data", "*.txt")
Console.WriteLine(Path.GetFileName(f))
Next
Console.WriteLine(Path.GetExtension("report.final.csv"))
Console.WriteLine(Path.GetFileNameWithoutExtension("report.final.csv"))
Console.WriteLine(Path.ChangeExtension("photo.jpeg", ".jpg"))
Console.WriteLine(Directory.GetDirectories("data").Length)
End Sub
End Module
a.txt
.csv
report.final
photo.jpg
1
Use Path.Combine to build paths; it inserts the right separator for
the operating system.
My.Computer.FileSystem
Windows Forms and older VB projects also have the My namespace, with
shortcuts like My.Computer.FileSystem.ReadAllText(path) and
My.Computer.FileSystem.CopyDirectory(source, target). In modern
console projects, System.IO is the standard choice.
Common mistakes
- Forgetting
Usingon streams — the file stays locked, and buffered text may never be written. - Not handling
FileNotFoundException,UnauthorizedAccessException, andIOExceptionfor files you don't control.