Aufgrund einer Diskussion, ob nun My.Computer.FileSystem oder System.IO besser sei, die kürzlich stattfand (einige haben sie vielleicht mitbekommen), und weil ich ein Verfechter von System.IO bin, war ich überrascht, dass es tatsächlich etwas gibt, bei dem My.Computer.FileSystem besser ist. Es handelt sich dabei um das Kopieren von Verzeichnissen.
Das konnte ich natürlich nicht auf mir sitzen lassen, und deshalb habe mich daran gemacht eine Extension für DirectoryInfo zu schreiben, die die My.Computer.FileSystem.CopyDirectory-Methode schlagen kann. Und das ist dabei herausgekommen:
Spoiler anzeigen
Ich habe alles in den XML-Kommentaren erklärt, weshalb ich das hier nun nicht mehr tun werde.
Zusätzlich zu CopyTo ist auch eine verbesserte MoveTo-Funktion dabei.
Den entsprechenden C#-Code werde ich (aufgrund von Platzmangel) noch nachreichen.
Das konnte ich natürlich nicht auf mir sitzen lassen, und deshalb habe mich daran gemacht eine Extension für DirectoryInfo zu schreiben, die die My.Computer.FileSystem.CopyDirectory-Methode schlagen kann. Und das ist dabei herausgekommen:
VB.NET-Quellcode
- Public Module DirectoryInfoExtensions
- ''' <summary>
- ''' Kopiert das Verzeichnis an den angegebenen Ort.
- ''' </summary>
- ''' <param name="destDirName">Name und Pfad des Verzeichnisses, in das der Inhalt dieses Verzeichnisses kopiert werden soll.</param>
- ''' <param name="merge">Gibt an, ob beim Vorhandensein des Zielverzeichnisses fortgefahren werden soll.</param>
- ''' <param name="options">Gibt an, wie verfahren werden soll, wenn Dateien aus dem Ausgangsverzeichnis im Zielverzeichnis bereits vorhanden sind.</param>
- ''' <returns>Ein neues DirectoryInfo-Objekt, das das Zielverzeichnis darstellt.</returns>
- ''' <exception cref="System.IO.IOException">Tritt auf, wenn "merge" false ist und der Zielordner bereits existiert, oder wenn OverwriteOptions.ThrowError übergeben wurde und eine zu kopierende Datei am Zielort bereits existiert.</exception>
- <Extension>
- Public Function CopyTo(dir As DirectoryInfo, destDirName As String, merge As Boolean, options As OverwriteOptions) As DirectoryInfo
- Dim result = New DirectoryInfo(destDirName)
- If result.Exists Then
- If Not merge Then Throw New IOException("Der Ordner """ & Convert.ToString(result.FullName) & """ existiert bereits.")
- Else
- result.Create()
- End If
- For Each d In dir.EnumerateDirectories()
- d.CopyTo(Path.Combine(destDirName, d.Name), merge, options)
- Next
- For Each f In dir.EnumerateFiles()
- Dim newPath = Path.Combine(result.FullName, f.Name)
- Select Case options
- Case OverwriteOptions.None
- If File.Exists(newPath) Then Throw New IOException("Die Datei """ & Convert.ToString(newPath) & """ existiert bereits.")
- f.CopyTo(newPath)
- Case OverwriteOptions.DontOverwrite
- If Not File.Exists(newPath) Then f.CopyTo(newPath)
- Case OverwriteOptions.OverwriteAll
- f.CopyTo(newPath, True)
- Case OverwriteOptions.OverwriteWhenNewer
- Dim newF = New FileInfo(newPath)
- If Not newF.Exists OrElse newF.LastWriteTime > f.LastWriteTime Then
- f.CopyTo(newPath, True)
- End If
- Case OverwriteOptions.Rename
- Dim count = 1
- While File.Exists(newPath)
- count += 1
- newPath = Path.Combine(result.FullName, String.Concat(Path.GetFileNameWithoutExtension(f.Name), " (", count, ")", f.Extension))
- End While
- f.CopyTo(newPath)
- End Select
- Next
- Return result
- End Function
- ''' <summary>
- ''' Kopiert das Verzeichnis an den angegebenen Ort.
- ''' </summary>
- ''' <param name="destDirName">Name und Pfad des Verzeichnisses, in das der Inhalt dieses Verzeichnisses kopiert werden soll.</param>
- ''' <returns>Ein neues DirectoryInfo-Objekt, das das Zielverzeichnis darstellt.</returns>
- ''' <exception cref="System.IO.IOException">Tritt auf, wenn der Zielordner bereits existiert, oder wenn eine zu kopierende Datei am Zielort bereits existiert.</exception>
- <Extension>
- Public Function CopyTo(dir As DirectoryInfo, destDirName As String) As DirectoryInfo
- Return dir.CopyTo(destDirName, False, OverwriteOptions.None)
- End Function
- ''' <summary>
- ''' Verschiebt das Verzeichnis an den angegebenen Ort.
- ''' </summary>
- ''' <param name="destDirName">Name und Pfad des Verzeichnisses, in das der Inhalt dieses Verzeichnisses verschoben werden soll.</param>
- ''' <param name="merge">Gibt an, ob beim Vorhandensein des Zielverzeichnisses fortgefahren werden soll.</param>
- ''' <param name="options">Gibt an, wie verfahren werden soll, wenn Dateien aus dem Ausgangsverzeichnis im Zielverzeichnis bereits vorhanden sind.</param>
- ''' <returns>Ein neues DirectoryInfo-Objekt, das das Zielverzeichnis darstellt.</returns>
- ''' <exception cref="System.IO.IOException">Tritt auf, wenn "merge" false ist und der Zielordner bereits existiert, oder wenn OverwriteOptions.None übergeben wurde und eine zu kopierende Datei am Zielort bereits existiert.</exception>
- <Extension>
- Public Function MoveTo(dir As DirectoryInfo, destDirName As String, merge As Boolean, options As OverwriteOptions) As DirectoryInfo
- Dim result = New DirectoryInfo(destDirName)
- If result.Exists Then
- If Not merge Then
- Throw New IOException("Der Ordner """ & Convert.ToString(result.FullName) & """ existiert bereits.")
- End If
- Else
- result.Create()
- End If
- For Each d In dir.EnumerateDirectories()
- d.MoveTo(Path.Combine(destDirName, d.Name), merge, options)
- Next
- For Each f In dir.EnumerateFiles()
- Dim newPath = Path.Combine(result.FullName, f.Name)
- Select Case options
- Case OverwriteOptions.None
- If File.Exists(newPath) Then Throw New IOException("Die Datei """ & Convert.ToString(newPath) & """ existiert bereits.")
- f.MoveTo(newPath)
- Case OverwriteOptions.DontOverwrite
- If Not File.Exists(newPath) Then f.MoveTo(newPath)
- Case OverwriteOptions.OverwriteAll
- Dim newF1 = New FileInfo(newPath)
- If newF1.Exists Then newF1.Delete()
- f.MoveTo(newPath)
- Case OverwriteOptions.OverwriteWhenNewer
- Dim newF2 = New FileInfo(newPath)
- If newF2.Exists Then
- If newF2.LastWriteTime > f.LastWriteTime Then
- newF2.Delete()
- f.MoveTo(newPath)
- End If
- Else
- f.MoveTo(newPath)
- End If
- Case OverwriteOptions.Rename
- Dim count = 1
- While File.Exists(newPath)
- count += 1
- newPath = Path.Combine(result.FullName, String.Concat(Path.GetFileNameWithoutExtension(f.Name), " (", count, ")", f.Extension))
- End While
- f.MoveTo(newPath)
- End Select
- Next
- dir.Delete()
- Return result
- End Function
- End Module
- ''' <summary>
- ''' Gibt an, wie bei einem Kopiervorgang verfahren werden soll, wenn die Zieldatei bereits existiert.
- ''' </summary>
- Public Enum OverwriteOptions
- ''' <summary>
- ''' Wenn die Datei bereits existiert, wird ein Fehler ausgelöst.
- ''' </summary>
- ThrowError
- ''' <summary>
- ''' Dateien werden nie überschrieben.
- ''' </summary>
- DontOverwrite
- ''' <summary>
- ''' Dateien werden immer überschrieben.
- ''' </summary>
- OverwriteAll
- ''' <summary>
- ''' Dateien werden nur überschrieben, wenn sie älter sind als die neue Datei.
- ''' </summary>
- OverwriteWhenNewer
- ''' <summary>
- ''' Neue Dateien werden umbenannt, wenn die Zieldatei existiert.
- ''' </summary>
- Rename
- End Enum
Ich habe alles in den XML-Kommentaren erklärt, weshalb ich das hier nun nicht mehr tun werde.
Zusätzlich zu CopyTo ist auch eine verbesserte MoveTo-Funktion dabei.
Den entsprechenden C#-Code werde ich (aufgrund von Platzmangel) noch nachreichen.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()