Rubrik: Dateisystem · Dateien - allgemein | VB-Versionen: VB.NET | 24.09.07 |
Fortschrittsanzeige für Copy/Move selber erstellen (.NET) Hier wird gezeigt, wie sich eine eigene Fortschrittsanzeige beim Kopieren/Verschieben von Dateien realisieren lässt. | ||
Autor: Lars Konschak | Bewertung: | Views: 16.887 |
ohne Homepage | System: WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Während eines Kopier-/Verschiebevorganges von Dateien ist es der Benutzer gewöhnt, dass man ihm den Kopier-/Verschiebefortschritt in Form einer Progressbar mitteilt. Leider teilen einem aber die Objekte "FileInfo" und "DirectoryInfo" den Fortschritt nicht mit, um diesen in eine Progressbar abbilden zu können (sofern man diese Objekte für das Verschieben und Kopieren benutzt).
Um dieses realisieren zu können, bieten sich unter anderem folgende 2 Methoden an:
- Kopieren/Verschieben über die API
Über die entsprechende API-Methode ist es aber zu kompliziert
- My.Computer.FileSystem.MoveFile bzw. My.Computer.FileSystem.CopyFile
Nun möchte man ja unter Umständen den Fortschritt aber gar nicht mit dem uns bekannten Fortschrittdialog des Explorers darstellen, sondern stattdessen durch eine Progressbar, welche sich in einem StatusStrip befindet. Oder vielleicht durch einen komplett eigenen Dialog á la Total Commander. Dazu müssen wir selber die Datei Stück für Stück in das Zielverzeichnis schreiben. Dadurch erhalten wir die Möglichkeit, den Fortschritt in eine Progressbar abzubilden.
Der folgende Code demonstriert, wie man auf einfache Weise so etwas implementieren kann.
Imports System.IO Public Class Form1 Private WithEvents m_Button As New Button Private WithEvents m_Progressbar As New ProgressBar Private m_Label As New Label
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Formular anpassen With Me .Text = "Kopieren mit einer Fortschrittanzeige" .Width = 462 .Height = 100 End With ' benötigte Objekte konfigurieren With m_Button .Text = "Start" .Top = 25 .Left = 343 End With With m_Progressbar .Top = 25 .Left = 20 .Width = 300 End With With m_Label m_Label.Text = "0%" .Left = (m_Progressbar.Width - 20) / 2 + 20 .Top = 10 End With ' Objekte dem Formular hinzufügen Me.Controls.Add(m_Button) Me.Controls.Add(m_Progressbar) Me.Controls.Add(m_Label) End Sub
Private Sub m_Button_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles m_Button.Click ' Quelldatei auswählen Dim sourcefile As FileInfo With New OpenFileDialog .Title = "Bitte eine Datei auswählen" If .ShowDialog = Windows.Forms.DialogResult.OK Then sourcefile = New FileInfo(.FileName) Else Exit Sub End If End With ' Zielverzeichnis auswählen Dim target As String With New FolderBrowserDialog .Description = "Bitte das Zielverzeichnis angeben" If .ShowDialog = Windows.Forms.DialogResult.OK Then target = .SelectedPath Else Exit Sub End If End With ' Kopiervorgang starten Copy sourcefile, target End Sub
Private Sub Copy(ByVal SourceFile As FileInfo, ByVal Target As String) ' Progressbar anpassen m_Progressbar.Value = 0 ' Es gilt hier zu beachten, dass der Maximumwert ein Integer ist und ' daher die Length-Angabe über dem Bereich des Integer hinaus liegen kann. ' In so einem Fall müsste man den Maximumwert anders definieren m_Progressbar.Maximum = SourceFile.Length Try ' Quelle Dim fsmsource As FileStream ' Zieldatei Dim fsmtarget As FileStream ' Größe des bei jedem Durchlauf einzulesenden Datenpaketes Dim buffersize As Int32 = 1024 * 30 ' (30 KByte) ' Enthält nacher die in buffersize angegeben Menge an ' eingelesenen Daten Dim buffer(buffersize) As Byte ' Ermittelt die tatsächliche eingelesene Menge an Daten ' im Bytearray readbyte Dim readbyte As Int32 ' Quelldatei fsmsource = New FileStream(SourceFile.FullName, FileMode.Open, _ FileAccess.Read, FileShare.Read) ' Zieldatei fsmtarget = New FileStream(Target + "\" + SourceFile.Name, _ FileMode.OpenOrCreate, FileAccess.Write) ' Daten nach und nach einlesen und im Zielstream wieder zurückschreiben While fsmsource.Position < fsmsource.Length ' Quelle einlesen readbyte = fsmsource.Read(buffer, 0, buffersize) ' In das Ziel schreiben fsmtarget.Write(buffer, 0, readbyte) ' Value Eigenschaft der Progressbar anpassen, das Label gibt ' den prozentualen Fortschritt an With m_Progressbar .Value += readbyte m_Label.Text = CStr(CInt(100 * .Value / .Maximum)) + "%" End With ' Reporten Application.DoEvents() End While ' Streams schließen fsmsource.Close() fsmtarget.Close() MsgBox("Datei erfolgreich kopiert", MsgBoxStyle.Information) m_Progressbar.Value = 0 m_Label.Text = "0%" Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "Error") End Try End Sub
End Class