File I/O & JSON
Read and write text files, CSV data, and JSON with System.IO and System.Text.Json — the building blocks of settings files, export features, and data interchange.
File.WriteAllText / File.ReadAllText (simple, one-shot) or StreamWriter / StreamReader (line-by-line, large files). For CSV, split each line on commas and trim quotes. For JSON, use JsonSerializer.Serialize(obj) to write and JsonSerializer.Deserialize(Of T)(json) to read — no third-party libraries needed in .NET 10. Always use Application.LocalUserAppDataPath as the base folder for data files so your app works without admin rights.
33.1 Reading and Writing Text Files
Use System.IO.File's one-shot methods for small files and StreamReader/StreamWriter for line-by-line processing of larger ones. Always wrap in Using to ensure the file handle is closed even on exceptions.
Imports System.IO ' --- Safe base folder (no admin rights needed) --- Dim dataDir = Application.LocalUserAppDataPath Directory.CreateDirectory(dataDir) ' ensure it exists Dim filePath = Path.Combine(dataDir, "notes.txt") ' ═══ ONE-SHOT (small files) ═══ File.WriteAllText(filePath, txtNotes.Text) ' write whole file Dim content = File.ReadAllText(filePath) ' read whole file Dim lines() = File.ReadAllLines(filePath) ' read into String array File.AppendAllText(filePath, Environment.NewLine & "New line") ' append ' ═══ STREAMING (large files, line-by-line) ═══ Using sw As New StreamWriter(filePath, append:=False) ' overwrite sw.WriteLine("StudentID,Name,Grade,Class") ' header For Each s In students sw.WriteLine($"{s.StudentID},{s.Name},{s.Grade},{s.Class}") Next End Using ' file closed here even if exception occurs Using sr As New StreamReader(filePath) Dim header = sr.ReadLine() ' skip header row Dim line = sr.ReadLine() Do While line IsNot Nothing Dim parts = line.Split(","c) If parts.Length = 4 Then Dim s As New Student With { .Name = parts(1).Trim(), .Grade = CDbl(parts(2)), .Class = parts(3).Trim() } students.Add(s) End If line = sr.ReadLine() Loop End Using ' --- Check existence before reading --- If File.Exists(filePath) Then content = File.ReadAllText(filePath) Else MessageBox.Show("File not found.") End If
33.2 CSV Import and Export
CSV (Comma-Separated Values) is the simplest interchange format — readable by Excel, importable by databases, and trivial to write. Quote fields that may contain commas. For production use, consider a dedicated CSV library, but for school projects the manual approach below is sufficient.
' --- Export List(Of Student) to CSV --- Private Sub ExportCSV(path As String, students As List(Of Student)) Using sw As New StreamWriter(path, append:=False, encoding:=Text.Encoding.UTF8) sw.WriteLine("StudentID,Name,Grade,Class") For Each s In students ' Quote name in case it contains a comma sw.WriteLine($'{s.StudentID},"{s.Name}",{s.Grade},{s.Class}') Next End Using MessageBox.Show($"Exported {students.Count} rows to {path}") End Sub ' --- Import CSV → List(Of Student) --- Private Function ImportCSV(path As String) As List(Of Student) Dim result As New List(Of Student) Dim lines = File.ReadAllLines(path) For i = 1 To lines.Length - 1 ' skip header (index 0) Dim parts = lines(i).Split(","c) If parts.Length < 4 Then Continue For Dim grade As Double If Not Double.TryParse(parts(2), grade) Then Continue For result.Add(New Student With { .StudentID = CInt(parts(0)), .Name = parts(1).Trim(""""c), ' strip surrounding quotes .Grade = grade, .Class = parts(3).Trim() }) Next Return result End Function ' --- OpenFileDialog integration --- Private Sub btnImport_Click(...) Using dlg As New OpenFileDialog() dlg.Filter = "CSV files|*.csv|All files|*.*" dlg.Title = "Import Students from CSV" If dlg.ShowDialog() = DialogResult.OK Then students = ImportCSV(dlg.FileName) _bs.DataSource = students.ToList() MessageBox.Show($"Imported {students.Count} students.") End If End Using End Sub
33.3 JSON with System.Text.Json
JSON is the standard format for configuration files, API responses, and data interchange. .NET 10 includes System.Text.Json in the base library — no NuGet package needed. Use JsonSerializerOptions with WriteIndented = True for human-readable output.
Imports System.Text.Json ' --- Serialize: object → JSON string --- Dim opts As New JsonSerializerOptions() With {.WriteIndented = True} Dim json = JsonSerializer.Serialize(students, opts) ' Result: ' [ ' { "StudentID": 1, "Name": "Ahmad Farid", "Grade": 88, "Class": "4A" }, ' ... ' ] ' --- Write to file --- File.WriteAllText(Path.Combine(dataDir, "students.json"), json) ' --- Deserialize: JSON string → typed object --- Dim loaded = JsonSerializer.Deserialize(Of List(Of Student))( File.ReadAllText(Path.Combine(dataDir, "students.json"))) ' --- Application settings pattern --- Public Class AppSettings Public Property LastOpenedFile As String Public Property Theme As String = "Light" Public Property MaxResults As Integer = 100 End Class Private _settingsPath = Path.Combine(Application.LocalUserAppDataPath, "settings.json") Function LoadSettings() As AppSettings If Not File.Exists(_settingsPath) Then Return New AppSettings() Try Return JsonSerializer.Deserialize(Of AppSettings)(File.ReadAllText(_settingsPath)) Catch Return New AppSettings() ' corrupt file → fresh defaults End Try End Function Sub SaveSettings(s As AppSettings) File.WriteAllText(_settingsPath, JsonSerializer.Serialize(s, New JsonSerializerOptions With {.WriteIndented=True})) End Sub
Type in the editor, click Save to write to the virtual file, and Read to load it back. Append adds to the existing content. The file display shows the raw bytes as they'd appear on disk.
Export the student list to a virtual CSV file. Edit the CSV text manually, then import it back — the grid updates to reflect any changes you made.
| — export then import — |
Serialise the student list to JSON with JsonSerializer.Serialize, edit the JSON, and deserialise back. Also try the AppSettings pattern — save and load a settings object.
| — deserialise to see data — |
33.4 GitHub Copilot — JSON Settings Manager
' Generate a generic settings manager that uses System.Text.Json to load and save any serialisable class to a JSON file in LocalUserAppDataPath. Include a LoadOrDefault(Of T) function that returns a new T() if the file is missing or corrupt.'Imports System.IO, System.Text.Json
Module SettingsManager
Private _opts As New JsonSerializerOptions() With {.WriteIndented = True}
Function LoadOrDefault(Of T As New)(fileName As String) As T
Dim path = Path.Combine(Application.LocalUserAppDataPath, fileName)
If Not File.Exists(path) Then Return New T()
Try
Dim json = File.ReadAllText(path)
Return JsonSerializer.Deserialize(Of T)(json) ?? New T()
Catch
Return New T() ' corrupt JSON → safe default
End Try
End Function
Sub Save(Of T)(fileName As String, obj As T)
Dim path = Path.Combine(Application.LocalUserAppDataPath, fileName)
Directory.CreateDirectory(Path.GetDirectoryName(path))
File.WriteAllText(path, JsonSerializer.Serialize(obj, _opts))
End Sub
End Module
' --- Usage ---
Dim settings = SettingsManager.LoadOrDefault(Of AppSettings)("settings.json")
settings.Theme = "Dark"
SettingsManager.Save("settings.json", settings)
Lesson Summary
- Use File.WriteAllText / ReadAllText for small, whole-file operations and StreamWriter / StreamReader in Using blocks for line-by-line processing of larger files.
- Always build file paths with Path.Combine and store data files under
Application.LocalUserAppDataPath— this is a per-user folder that never requires admin rights. - For CSV, write a header row first, then one row per record. On import, split on commas, skip the header (index 0), validate each field with
TryParse, and skip malformed lines withContinue For. - JsonSerializer.Serialize(obj, opts) converts any class or collection to a JSON string. Deserialize(Of T)(json) rebuilds the typed object. Set
WriteIndented = Truefor human-readable files. - Wrap Deserialize in Try/Catch and return a
New T()on failure — JSON files can be hand-edited and become corrupt. - Check
File.Exists(path)before reading. UseDirectory.CreateDirectory(dir)before writing — it is a no-op if the folder already exists.
Exercises
Exercise 33.1 — Student CSV Import/Export
- Add Export CSV and Import CSV buttons to the student form from Lesson 31. Export uses SaveFileDialog; import uses OpenFileDialog.
- On import, validate each row: StudentID must parse as Integer, Grade 0–100, Name non-empty. Collect all validation errors and show them in a summary MessageBox.
- Copilot challenge: "Generate a Sub that reads a CSV file asynchronously using File.ReadAllLinesAsync, processes each line with LINQ, and shows a ProgressBar as rows are added to the DataTable"
Exercise 33.2 — JSON Settings File
- Create an AppSettings class: LastOpenedFile, WindowWidth, WindowHeight, DefaultClass, AutoSave (Boolean). Persist it to settings.json in LocalUserAppDataPath.
- On Form_Load call LoadOrDefault. On Form_Closing save settings. Test that window size is remembered across runs.
- Copilot challenge: "Extend AppSettings to store a RecentFiles property as List(Of String) (max 10). Show the list in a ToolStripMenuItem submenu on a File menu."
Related Resources
← Lesson 32
LINQ & Collections.
Lesson 34 →
Async Programming.
MS Docs — System.IO
File, StreamReader, StreamWriter reference.
MS Docs — System.Text.Json
JsonSerializer, JsonSerializerOptions guide.
Featured Books
Visual Basic 2022 Made Easy
File I/O chapters: reading, writing, CSV parsing, and application settings patterns.
View on Amazon →