vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Zippen wie die Profis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2018
 
zurück
Rubrik: Dateisystem · Dateien lesen/schreiben   |   VB-Versionen: VB2005, VB200819.03.10
Datei splitten und wieder zusammenfügen

Dieser Tipp zeigt, wie eine Datei in einzelne Segmente gesplittet und wieder zusammengefügt werden kann.

Autor:   Lars KonschakBewertung:     [ Jetzt bewerten ]Views:  11.386 
ohne HomepageSystem:  Win2k, WinXP, Vista, Win7, Win8, Win10 Beispielprojekt auf CD 

Manchmal ist es nicht möglich, eine Datei aufgrund ihrer Größe als ganzes zu übertragen. Sei es, weil der Emailprovider die Anhanggröße einer Mail beschränkt oder ein Speichermedium nicht über genügend Platz verfügt. Szenarien gibt es viele.

Als Lösung bietet sich ein Splitten der Datei in einzelne Segmenten an. Die einzelnen Dateisegmente können dann bei Bedarf wieder zu einer Datei zusammengefügt werden. Genau dieses demonstriert dieses Beispiel anhand einer einfachen Klasse. Ich habe zugunsten der Lesbarkeit dieses Beispiels auf diverse Absicherungen verzichtet, die man später aber implementieren sollte (die Segmentgröße darf als Beispiel nicht größer als der Bereich eines Int32 sein usw.).

Imports System.IO
 
''' <summary>
''' Größeneinheit des einzelnen Segmentes
''' </summary>
''' <remarks></remarks>
Public Enum SizeUnit
  KByte
  MByte
  GByte
End Enum
 
Public Class SplittingJoining
  ''' <summary>
  ''' Datei in Segmente splitten
  ''' </summary>
  ''' <param name="SourceFile">Quelldatei</param>
  ''' <param name="TargetFolder">Zeilverzeichnis</param>
  ''' <param name="Unit">Dateneinheitgröße</param>
  ''' <param name="Size">Größe der Dateneinheit</param>
  ''' <remarks></remarks>
  Public Sub SplitFile(ByVal SourceFile As String, _
    ByVal TargetFolder As String, _
    ByVal Unit As SizeUnit, _
    ByVal Size As Integer)
 
    ' Dient zur Überprüfung, ob das letzte Segment eingelesen wird
    Dim controlBuffer As Int32 = 0
 
    ' Definiert die Anzahl an Bytes, die Stückweise einzulesen und zu schreiben sind 
    Dim bytesToRead As Int32 = 0
 
    ' Tatsächliche eingelesene Bytes  
    Dim bytesRead As Int32 = 0
 
    ' Wird den Namen des jeden neu zu schreibenden Dateisegmentes beinhalten
    Dim currDstFile As String
 
    ' Zähler für die Dateiendungen
    Dim counter As Int32 = 1
 
    ' Dient zum einlesen der Quelldatei
    Dim srcStream As FileStream
 
    ' Abhängig von der Benutzerangabe bezüglich der Dateiteinheitengröße 
    ' den Lesebuffer festlegen
    If Unit = SizeUnit.KByte Then
      bytesToRead = Size * 1024
    ElseIf Unit = SizeUnit.MByte Then
      bytesToRead = Size * (1024 * 1024)
    ElseIf Unit = SizeUnit.GByte Then
      bytesToRead = Size * (1024 * 1024 * 1024)
    End If
 
    controlBuffer = bytesToRead
 
    ' Filestream aus der Quelldatei erstellen
    srcStream = New FileStream(SourceFile, FileMode.Open, _
      FileAccess.Read, FileShare.None)
 
    Try
      Dim buffer(bytesToRead - 1) As Byte
      Do
        ' Dateiendung ermitteln. 
        ' Diese wird gegebenfalls mit Nullen aufgefüllt.
        If counter < 10 Then
          ' Liegt die Zahl unter 10, so wird der Dateieindung zwei 
          ' Nullen vorangestellt (.001, 002 usw.)
          currDstFile = "00" & counter.ToString()
        ElseIf counter < 100 Then
          ' Liegt die Zahl unter 100, so wird der Dateieindung eine 
          ' Null vorangestellt (.020, 021 usw.)
          currDstFile = "0" & counter.ToString()
        Else
          currDstFile = counter.ToString()
        End If
 
        ' Name des neu zu schreibenden Dateisegmentes
        currDstFile = TargetFolder + "\" + _
          Path.GetFileName(SourceFile) + "." + currDstFile
 
        ' Letztes Segment erstellen?
        If ((srcStream.Length - srcStream.Position) < controlBuffer) _
          OrElse ((srcStream.Length - srcStream.Position) = controlBuffer) Then
 
          ' Einzulesende Restgröße ermitteln
          bytesToRead = CInt((srcStream.Length - srcStream.Position))
 
          If bytesToRead = 0 Then
            ' Es gibt nichts mehr einzulesen
            Exit Do
          End If
        End If
 
        ' Daten einlesen
        bytesRead = srcStream.Read(buffer, 0, bytesToRead)
 
        ' Dateisegment schreiben
        Using dstStream As New FileStream(currDstFile, _
          FileMode.Create, FileAccess.ReadWrite, FileShare.None)
          Try
 
            dstStream.Write(buffer, 0, bytesToRead)
 
          Catch ex As Exception
            MessageBox.Show("Beim schreiben der Daten trat folgender Fehler auf:" + _
              vbCrLf + ex.Message, _
              "Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Exit Sub
          End Try
        End Using
 
        ' Zähler erhöhen
        counter += 1
      Loop While bytesRead = controlBuffer AndAlso bytesToRead > 0
 
      MessageBox.Show("Die Datei wurde erfolgreich gesplittet", _
        "Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Information)
 
    Catch ex As Exception
      MessageBox.Show("Beim lesen / schreiben der Daten trat folgender Fehler auf:" + _
        vbCrLf + ex.Message, _
        "Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
  End Sub
  ''' <summary>
  ''' Setzt eine Datei aus Dateifragmenten wieder zusammen.
  ''' </summary>
  ''' <param name="f">Erstes gesplittetes Dateisegment (Extension 001!!)</param>
  ''' <param name="TargetFolder">Zielverzeichnis</param> 
  Public Sub JoinFileSegments(ByVal f As String, _
    ByVal TargetFolder As String)
 
    ' Zähler für die Dateiendungen 
    Dim counter As Integer = 1
 
    ' Bytes, die einzulesen sind
    Dim byteToRead As Integer = 0
 
    ' Beinhaltet die eingelesenen Daten
    Dim byteRead As Integer = 0
 
    ' Liste wird die Dateisegmente enthalten
    Dim fileList As New List(Of String)()
 
    Dim b As String = ""
 
    ' Alle Dateisegmente in einer List(Of String)speichern
    Do
      If counter < 10 Then
        b = "00" & counter.ToString
      ElseIf counter < 100 Then
        b = "0" & counter.ToString
      Else
        b = counter.ToString
      End If
 
      Dim filename As String = Path.GetDirectoryName(f) + "\" + _
        Path.GetFileNameWithoutExtension(f) + "." + b
 
      If File.Exists(filename) Then
        fileList.Add(filename) ' Dateisegment in die Liste aufnehmen
      End If
 
      counter += 1
    Loop While File.Exists(Path.GetDirectoryName(f) + "\" + _
      Path.GetFileNameWithoutExtension(f) + "." + b)
 
    Try
      ' Ziel-FileStream erstellen, durch welchem die Dateisegmente 
      ' in eine Zieldatei geschrieben werden
      Dim dstStream As New FileStream(TargetFolder + "\" + _
        Path.GetFileNameWithoutExtension(f), _
        FileMode.Create, FileAccess.Write, FileShare.None)
 
      ' Enhält die einzulesenden Daten
      Dim filedata As Byte()
 
      ' Alle Dateien aus der Liste auslesen und in eine Zieldatei speichern
      For Each fi As String In fileList
 
        ' FileStream, der das Datei-Segment einliest.
        Using sceStream As New FileStream(fi, FileMode.Open, _
          FileAccess.Read, FileShare.Read)
 
          ' Länge der einzulesenden Daten ermitteln
          byteToRead = CInt(sceStream.Length)
 
          filedata = New Byte(byteToRead - 1) {}
 
          ' Daten einlesen
          byteRead = sceStream.Read(filedata, 0, byteToRead)
 
          ' Daten schreiben
          dstStream.Write(filedata, 0, byteRead)
        End Using
      Next
      dstStream.Close()
    Catch ex As Exception
      MessageBox.Show(ex.Message)
      Exit Sub
    End Try
 
    MessageBox.Show("Datei-Joining wurde erfolgreich beendet")
  End Sub
End Class

Dieser Tipp wurde bereits 11.386 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (5 Beiträge)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2018 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel