VB.NET Textdatei schreiben

VB.NET Textdatei schreiben
VB.NET Textdatei schreiben

VB.NET Textdatei schreiben

Wenn Du in VB.NET eine Textdatei schreiben möchtest, bist Du hier in diesem Beitrag genau richtig!

Das von Textdateien verwendete Format findet fast überall Anwendung, daher ist es kein Wunder, dass gerade dieses Format das am einfachsten zu Lesende ist.

Falls Du Dich alternativ dafür interessieren solltest, wie Du eine Textdatei auslesen kannst, schaue doch gerne auch in meinem anderen Beitrag VB.NET Textdatei einlesen vorbei.

Code

Gestalte Dir für den folgenden Schritt am besten eine ähnliche Oberfläche wie die hier drunter und im Anschluss legen wir mit dem Code los:

VB.NET Textdatei erstellen GUI

Datei schreiben

Erforderliche Klassen und Methoden

Die Möglichkeit zur Erstellung, bzw. Schreiben, Lesen und anderen dateibezogene Operationen finden wir in der File-Klasse.

Wenn man in der .NET Framework Dokumentation nach unserem benötigten Begriff „write“ sucht, findet man folgende aktuell wichtige Methoden:

WriteAllText(filepath, contents)

Diese Methode schreibt die übergebenen Zeichen in eine Textdatei in den angegebenen Dateipfad.

Wenn die Datei nicht schon existiert, wird sie erstellt und andernfalls überschrieben.

WriteAllText(filepath, contents, encoding)

Hier passiert alles eigentlich analog zur Methode hier drüber, allerdings wird in diesem Fall das Encoding ausdrücklich angegeben.

WriteAllTextAsync(filepath, contents, cancellationToken)

Diese Methode ist noch relativ neu und steht erst in eurem Projekt ab dem .NET 5 Framework zur Verfügung.

Besonders bei großen, bzw. größeren Dateien zeigt diese Methode ihre Vorteile durch den asynchronen Dateizugriff.

Los geht’s

Gehe nun z. B. über den Form-Designer und einem Doppelklick auf den Button in den Ereignishandler für das Button Klick-Ereignis.

Die Datei können wir dann wie folgt in unserem Handler erstellen, bzw. schreiben:

    Private Sub btnWriteFile_Click(sender As Object, e As EventArgs) Handles btnWriteFile.Click
        Dim filepath = tbFilepath.Text.Trim()
        Dim content = tbContent.Text

        WriteFileSync(filepath, content)
        ' WriteFileWithEncodingSync(filepath, content)
        ' WriteFileAsync(filepath, content)
    End Sub

Im ersten Schritt hole ich mir den Dateipfad für die geplante Datei und entferne eventuelle Leerzeichen am Anfang und Ende.

Den Inhalt der zu erstellenden Datei legen wir in die Variable „content“, Welcher dem Text der „tbContent“-Textbox entspringt.

Im letzten Schritt beginne ich dann mit dem Schreiben der Textdatei, dazu habe ich verschiedene weitere Methoden angelegt.

WriteFileSync(filepath, content)

Hier findet die wohl simpelste Variante statt, Text in eine Textdatei zu schreiben.

Wir führen die „WriteAllText„-Methode der File-Klasse mit passenden Parameter wie den Dateipfad und den zu schreibenden Zeichen, sprich dem Inhalt aus.

Den Schreibvorgang selbst habe ich mit einem „Try Catch“-Block zum Abfangen globaler Fehler verziert.

WriteFileWithEncodingSync(filepath, content)

Neben unserer Angabe eines expliziten Encodings passiert hier nichts anderes als im Beispiel hier drüber.

WriteFileAsync(filepath, content)

Dies ist die oben bereits angesprochene neue Variante, eine Datei zu schreiben, ansonsten ist es eigentlich gleich der ersten Methode „WriteFileSync“.

Anwendungsbeispiele

Um das Ganze ggf. ein wenig nahbarer, bzw. greifbarer zu machen, möchte ich Dir mindestens ein Anwendungsbeispiel zeigen.

Konfigurationsdateien speichern/laden

Textdatei schreiben – Ini-Dateien Konfigurationsdateien
Textdatei schreiben – Ini-Dateien Konfigurationsdateien

Im ersten Beispiel stelle ich Dir ein gutes und vor allem altbekanntes Problem der Softwareentwicklung dar.

Dabei geht es um das Einlesen und Speichern von Konfigurationsdateien.

Viele Computernutzer werden diese Dateien als Ini-Dateien – mit der Dateiendung .ini – kennen.

IniFile-Klasse

Im ersten Schritt erstellen wir uns eine sehr einfache und rudimentäre IniFile-Klasse.

Diese dient in erster Linie nur der Veranschaulichung, in VB.NET eine Textdatei zu schreiben, bzw. in VB.NET eine Textdatei zu schreiben (im Ini-File Format).

Neben dem Dateinamen, dem Verzeichnis und dem daraus resultierenden Dateipfad besitzt das Ini-File auch einen Namen.

Für Verbesserungen würde mir unter anderem die Verwendung verschiedener Encodings und Serializer einfallen.

Imports System.IO

Public Class IniFile

    ''' <summary>
    ''' Gets or Sets the path to the directory, containing the file
    ''' </summary>
    Public Property Directory As String

    ''' <summary>
    ''' Gets or Sets the filename of the file
    ''' </summary>
    Public Property FileName As String

    ''' <summary>
    ''' Returns the complete path to the ini file
    ''' </summary>
    Public ReadOnly Property FilePath As String
        Get
            Return Path.Combine(Directory, FileName)
        End Get
    End Property

    Public Property Sections As List(Of IniFileSection)

    Sub New()
        Sections = New List(Of IniFileSection)
    End Sub

    Public Async Function Save() As Task
        Dim contents = ToIniFileString()
        Await File.WriteAllTextAsync(FilePath, contents)
    End Function

    Public Shared Async Function Load(filePath As String) As Task(Of IniFile)
        Dim fileParts = filePath.Split("\")
        Dim iniFile = New IniFile()
        iniFile.Directory = String.Join("\", fileParts.Take(fileParts.Length - 1))
        iniFile.FileName = fileParts.Last()
        Dim contents = Await File.ReadAllTextAsync(filePath)
        Dim nonEmptyLines = contents.Split(Environment.NewLine).Where(Function(x) Not String.IsNullOrWhiteSpace(x))

        ' = nothing is a worarkound for "could be nothing" warning - #irony
        Dim currentSection As IniFileSection = Nothing
        For Each line In nonEmptyLines
            Dim isNewSection = line.StartsWith("[") AndAlso line.EndsWith("]")
            If isNewSection Then
                Dim sectionName = line.Replace("[", "]").Replace("]", "")
                currentSection = New IniFileSection(sectionName)
                iniFile.Sections.Add(currentSection)
                Continue For
            End If

            Dim isNewEntry = line.Contains("=")
            If isNewEntry Then
                Dim entryParts = line.Split("=")
                Dim key = entryParts(0)
                Dim value = entryParts(1)
                Dim entry = New IniFileSectionEntry(key, value)
                currentSection.Entries.Add(entry)
                Continue For
            End If
        Next
        Return iniFile
    End Function

    Public Function ToIniFileString() As String
        Dim sectionStrings = New List(Of String)
        For Each section In Sections
            sectionStrings.Add(section.ToIniFileString())
        Next
        Return String.Join(Environment.NewLine, sectionStrings)
    End Function

    Public Overrides Function ToString() As String
        Return $"IniFile: {FilePath}"
    End Function

End Class

IniFileSection-Klasse

Als nächstes kommt die IniFileSection-Klasse, Welche neben dem Namen der Sektion auch dessen Einträge beinhaltet.

Die gesamten Daten können wir dann mit Hilfe der kleinen Helper-Methode namens „ToIniFileString“ bekommen.

Public Class IniFileSection

    Public Property Name As String

    Public Property Entries As List(Of IniFileSectionEntry)

    Sub New(name As String)
        Me.Name = name
        Entries = New List(Of IniFileSectionEntry)
    End Sub

    Public Function ToIniFileString() As String
        Dim str = $"[{Name}]"
        For Each entry In Entries
            str &= $"{Environment.NewLine}{entry.ToIniFileString()}"
        Next
        Return str
    End Function

    Public Overrides Function ToString() As String
        Return $"IniFileSection: {Name}"
    End Function

End Class

IniFileSectionEntry-Klasse

Zum Schluss kommt die IniFileSectionEntry-Klasse, Welche den Schlüssel und den dahinter stehenden Wert beinhaltet.

Auch Diese hat die gleichnamige Helper-Funktion, um den Eintrag ini-konform umzuwandeln.

Public Class IniFileSectionEntry

    Public Property Key As String

    Public Property Value As String

    Sub New()
        Key = ""
        Value = ""
    End Sub

    Sub New(key As String, value As String)
        Me.Key = key
        Me.Value = value
    End Sub

    Public Function ToIniFileString() As String
        Return $"{Key}={Value}"
    End Function

    Public Overrides Function ToString() As String
        Return $"IniFileSectionEntry: {Key}={Value}"
    End Function

End Class

Verwendungsbeispiel in einer Konsolenanwendung

Zu guter Letzt kommt das Modul für die Konsole, worin wir 1-2 Beispiel-Aufrufe durchführen.

Lade Dir ggf. eines des Beispielprojekte herunter, dann kannst Du Dir das Ganze im Detail ansehen.

Module Program

    Sub Main(args As String())
        Console.Title = "TextFileCreateIniFile"
        DoExampleReadWrite()
    End Sub

    Public Async Sub DoExampleReadWrite()
        ' A
        ' put the config file into the same directory as the exe file
        ' or change the path
        Dim ini = Await IniFile.Load(".\example-config.ini")
        Console.WriteLine("Press Enter to overwrite the first sections, first entries value with TEST")
        Console.ReadLine()
        ini.Sections(0).Entries(0).Value = "TEST"
        Console.WriteLine("Press Enter to save the changes to file")
        Console.ReadLine()
        Await ini.Save()
        Console.WriteLine("File saved, press enter to leave")
        Console.ReadLine()
    End Sub

End Module

Kompletter Code – VB.NET Textdatei schreiben

Imports System.IO

Public Class Form1

    Private Sub btnWriteFile_Click(sender As Object, e As EventArgs) Handles btnWriteFile.Click
        Dim filepath = tbFilepath.Text.Trim()
        Dim content = tbContent.Text

        WriteFileSync(filepath, content)
        ' WriteFileWithEncodingSync(filepath, content)
        ' WriteFileAsync(filepath, content)
    End Sub

    Private Sub WriteFileSync(filepath As String, content As String)
        Try
            File.WriteAllText(filepath, content)
        Catch ex As Exception
            MessageBox.Show("Couldn't write file sync: " & ex.Message)
        End Try
    End Sub

    Private Sub WriteFileWithEncodingSync(filepath As String, content As String)
        Dim encoding = System.Text.Encoding.UTF8
        Try
            File.WriteAllText(filepath, content, encoding)
        Catch ex As Exception
            MessageBox.Show("Couldn't write file sync with encoding: " & ex.Message)
        End Try
    End Sub

    ' only available with .NET 5
    ' not in .NET Framework Apps
    'Private Sub WriteFileAsync(filepath As String, content As String)
    '    Try
    '        File.WriteAllTextAsync(filepath, content)
    '    Catch ex As Exception
    '        MessageBox.Show("Couldn't write file async: " & ex.Message)
    '    End Try
    'End Sub

End Class

Downloads

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.