FileStream Bytes Überschreiben

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Wenn der Schreibvorgang erfolgreich ist, wird die aktuelle Position des
    Streams um die Anzahl der geschriebenen Bytes nach vorn verschoben.
    Wenn eine Ausnahme auftritt, wird die aktuelle Position des Streams
    nicht geändert.
    Das einzigste was ich gefunden habe bringt mich nicht wirklich weiter.
    So ich habe grad mal was zusammengecodet, ist etwas unsauber.

    Löscht die angegebenen byte aus einer großen Datei:

    VB.NET-Quellcode

    1. Private Sub RemoveDrive(ByVal c As StructureRemoveDrive)
    2. Dim fs As New FileStream(Resource, FileMode.Open, FileAccess.ReadWrite)
    3. Dim extendedPagedFile As FileStream = GetTempFile()
    4. For Each pt In Container
    5. If pt.VirtuallName = c.name Then
    6. Dim FileLength As Int64 = fs.Length
    7. Dim BytesRest As Int64 = FileLength - (pt.Pointer + pt.Count)
    8. Dim buffer() As Byte = New Byte(BufSize) {}
    9. Dim IState As New IDrive.IState
    10. IState.Operation = IDrive.OperationType.Delete
    11. fs.Position = pt.Pointer + pt.Count
    12. 'Datei Auslagern
    13. While (BytesRest > BufSize)
    14. fs.Read(buffer, 0, BufSize)
    15. extendedPagedFile.Write(buffer, 0, BufSize)
    16. BytesRest = (BytesRest - BufSize)
    17. IState.Value = Int((FileLength - BytesRest) * 100 / FileLength)
    18. Dispatcher.Invoke(c.handle, IState)
    19. End While
    20. fs.Read(buffer, 0, BytesRest)
    21. extendedPagedFile.Write(buffer, 0, BytesRest)
    22. 'ByteSize auf Auslagerungsdatei anpassen
    23. BytesRest = extendedPagedFile.Length
    24. extendedPagedFile.Position = 0
    25. fs.Position = pt.Pointer
    26. BackPointer(pt.Pointer, pt.Count)
    27. 'Datei Zusammenführen
    28. While (BytesRest > BufSize)
    29. extendedPagedFile.Read(buffer, 0, BufSize)
    30. fs.Write(buffer, 0, BufSize)
    31. BytesRest = (BytesRest - BufSize)
    32. IState.Value = Int((FileLength - BytesRest) * 100 / FileLength + extendedPagedFile.Length)
    33. Dispatcher.Invoke(c.handle, IState)
    34. End While
    35. extendedPagedFile.Read(buffer, 0, BytesRest)
    36. fs.Write(buffer, 0, BytesRest)
    37. IState.Value = 100
    38. Dispatcher.Invoke(c.handle, IState)
    39. extendedPagedFile.Close()
    40. FileIO.FileSystem.DeleteFile(extendedPagedFile.Name)
    41. fs.Close()
    42. Dispatcher.Invoke(Sub() Container.Remove(pt))
    43. Lock = False
    44. Exit Sub
    45. End If
    46. Next
    47. 'Throw New FileNotFoundException
    48. End Sub
    Wenn Du im Stream manipulieren willst, sieh Dir mal System.IO.MemoryStream an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Serow schrieb:

    eine 10GB Datei
    Solch unwichtige Details würde ich auch nicht in die Frage reinschreiben. :S
    Erstelle eine bedingte Kopie Deiner Datei, lies die Quelle blockwerise ein und schreib die manipulierten Daten wieder auf Platte.
    Nächster Block.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    MemoryStream, um Festplattenoperationen zu umgehen. Ist ja nun inzwischen out.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @ErfinderDesRades

    Der Code ist so aufgebaut:

    Nehmen wir mal an die Datei hat 3500 Bytes. Und es sollen ab dem 1000 Byte die nächsten 400 bytes entfernt werden.
    Es werden zuerst 2 FileStreams geöffnet einen temporären (tmp_fs) und einen der auf die Datei mit den 3500 Bytes (fs) zeigt. Als nächstes werden vom FileStream (fs) alle Bytes nach dem 1400 (1000 + 400) Byte in dem (tmp_fs) geschrieben. Danach wird die Länge vom fs auf 1000 gesetzt und die Bytes aus dem tmp_fs wieder angefügt. Um den Arbeitsspeicher nicht voll zuschreiben werden die Kopiervorgänge mit 5120 Bytes gepuffert.

    Ich hoffe ich habe das anschlich erklärt.
    Also hier mal der fertige Code mit dem man Bytes in einem FileStream Überschreiben kann.



    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' Bytes Überschreiben
    3. ''' </summary>
    4. ''' <param name="startPos">Der Anfang der zu löschenden Bytes.</param>
    5. ''' <param name="Count">Die Anzahl der zu löschenden Bytes</param>
    6. ''' <param name="insert">Die Bytes die an dieser Stelle einzufügen sind, dieser Block wird ungepuffert geschrieben.</param>
    7. ''' <param name="fs">Der derzeitige FileStream.</param>
    8. ''' <remarks></remarks>
    9. Sub InsertBytes(ByVal startPos As Long, ByVal Count As Long, ByVal Insert As Byte(), ByRef fs As FileStream)
    10. Dim tmpfilename As String = Path.GetTempFileName
    11. FileIO.FileSystem.CopyFile(fs.Name, tmpfilename, True)
    12. Dim extendedPagedFile As New FileStream(tmpfilename, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
    13. 'Länge bis zur start Position setzen
    14. fs.SetLength(startPos)
    15. 'Bytes einfügen
    16. fs.Position = startPos
    17. fs.Write(Insert, 0, Insert.Length)
    18. 'Datei zusammenführen
    19. Dim FileLength As Int64 = extendedPagedFile.Length - (startPos + Count)
    20. Dim BytesRest As Int64 = FileLength
    21. Dim BufSize As Int32 = 5120
    22. Dim arrDaten() As Byte = New Byte((BufSize) - 1) {}
    23. extendedPagedFile.Position = startPos + Count
    24. While (BytesRest > BufSize)
    25. extendedPagedFile.Read(arrDaten, 0, BufSize)
    26. fs.Write(arrDaten, 0, BufSize)
    27. BytesRest = (BytesRest - BufSize)
    28. End While
    29. extendedPagedFile.Read(arrDaten, 0, BytesRest)
    30. fs.Write(arrDaten, 0, BytesRest)
    31. extendedPagedFile.Close()
    32. FileIO.FileSystem.DeleteFile(extendedPagedFile.Name)
    33. End Sub
    du hast da immer noch 2 Kopier-Vorgänge: einmal komplett kopieren, und dann das drauf-kopieren was nach der Löschung kommt (unter überschreiben hätte ich mir vorgestellt, dass keine Bytes verschoben werden, sondern nur in einem Bereich ersetzt)
    mein Ansatz läuft auf eine Umbenennung und eine Umkopierung hinaus, weil umbenennen ist viel schneller als umkopieren

    Aber guck dirmal mein neuestes Experiment an:

    VB.NET-Quellcode

    1. Const bufSize As Integer = 128
    2. Dim buf(bufSize - 1) As Byte
    3. Dim read = bufSize
    4. Dim sFile = "C:\Programming\DotNet\VS10\VB10\A0Form\A0Form\frmA0Form - Kopie.vb"
    5. Using reader As New FileStream(sFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), _
    6. writer As New FileStream(sFile, FileMode.Open, FileAccess.Write, FileShare.ReadWrite)
    7. reader.Position = 200
    8. writer.Position = 100
    9. Do
    10. read = reader.Read(buf, 0, bufSize)
    11. writer.Write(buf, 0, read)
    12. Loop Until read < bufSize
    13. writer.Flush()
    14. writer.SetLength(writer.Position)
    15. End Using
    Die neue Datei wird auf sich selbst geschrieben

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()