197 lines
7.1 KiB
VB.net
197 lines
7.1 KiB
VB.net
Imports System.IO
|
|
Imports System.Runtime.Serialization.Formatters.Binary
|
|
|
|
Public Class FileContainer
|
|
Private _files As List(Of FileEntry)
|
|
Private _crypto As Encryption
|
|
Private _compression As Compression
|
|
Private _formatter As BinaryFormatter
|
|
|
|
<Serializable>
|
|
Public Class FileEntry
|
|
Public FileId As String
|
|
Public Contents As Byte()
|
|
End Class
|
|
|
|
''' <summary>
|
|
''' Gibt eine Auflistung der Dateien in Container zurück.
|
|
''' </summary>
|
|
''' <returns>Eine Liste von Objekten der Klasse FileContainer.FileEntry</returns>
|
|
Public ReadOnly Property Files As List(Of FileEntry)
|
|
Get
|
|
Return _files
|
|
End Get
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Erstellt eine Representation eines Datei Containers, der mit dem angegebenen Passwort geschützt ist.
|
|
''' Ist für das speichern von neuen Containern und für das laden vorhandener Container nötig.
|
|
''' </summary>
|
|
''' <param name="password">Das Passwort, mit dem der Container ver- und entschlüsselt wird</param>
|
|
''' <example>
|
|
''' Dim password = "meinpasswort"
|
|
''' Dim container = new FileContainer(password)
|
|
''' </example>
|
|
Public Sub New(password As String)
|
|
_crypto = New Encryption(password)
|
|
_compression = New Compression()
|
|
_formatter = New BinaryFormatter()
|
|
|
|
_files = New List(Of FileEntry)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Speichert einen Datei Container am angegebenen Pfad.
|
|
''' Davor werden die Dateien in Files komprimiert und dann verschlüsselt.
|
|
''' </summary>
|
|
''' <param name="path">Der Pfad mit Dateiname, unter dem der Container abgelegt wird.</param>
|
|
''' <see cref="Files"/>
|
|
''' <example>
|
|
''' container.AddFile("datei1.txt")
|
|
''' container.AddFile("datei2.pdf")
|
|
''' container.Save("container.enc")
|
|
''' </example>
|
|
Public Sub Save(path As String)
|
|
' 1. Serialize
|
|
Dim bFiles As Byte() = Serialize(_files)
|
|
' 2. Compress
|
|
Dim bFilesCompressed As Byte() = _compression.Compress(bFiles)
|
|
' 3. Encrypt
|
|
Dim bFilesEncrypted As Byte() = _crypto.Encrypt(bFilesCompressed)
|
|
|
|
BytesToFile(bFilesEncrypted, path)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Speichert einen Datei Container am angegebenen Pfad.
|
|
''' Davor werden die Dateien in Files komprimiert und dann verschlüsselt.
|
|
''' </summary>
|
|
''' <param name="path">Der Pfad mit Dateiname, unter dem der Container abgelegt wird.</param>
|
|
''' <example>
|
|
''' Public Async Sub foobar()
|
|
''' ...
|
|
''' container.AddFile("datei1.txt")
|
|
''' container.AddFile("datei2.pdf")
|
|
''' await container.SaveAsync("container.enc")
|
|
''' ...
|
|
''' End Sub
|
|
''' </example>
|
|
Public Async Function SaveAsync(path As String) As Task
|
|
' 1. Serialize
|
|
Dim bFiles As Byte() = Serialize(_files)
|
|
' 2. Compress
|
|
Dim bFilesCompressed As Byte() = Await _compression.CompressAsync(bFiles)
|
|
'Dim bFilesCompressed = bFiles
|
|
' 3. Encrypt
|
|
Dim bFilesEncrypted As Byte() = Await _crypto.EncryptAsync(bFilesCompressed)
|
|
|
|
BytesToFileAsync(bFilesEncrypted, path)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Lädt einen Datei Container aus dem angegebenen Pfad.
|
|
''' Anschließend werden die enthaltenen Dateien entschlüsselt, dekomprimiert und in Files abgelegt.
|
|
''' </summary>
|
|
''' <param name="path">Der Pfad mit Dateiname, von dem der Container geladen wird.</param>
|
|
''' <see cref="Files"/>
|
|
''' <example>
|
|
''' container.Load("container.enc")
|
|
''' Dim files As List(Of FileContainer.FileEntry) = container.Files
|
|
''' </example>
|
|
Public Sub Load(path As String)
|
|
Dim bFilesEncrypted As Byte() = FileToBytes(path)
|
|
|
|
' 1. Decrypt
|
|
Dim bFiles As Byte() = _crypto.Decrypt(bFilesEncrypted)
|
|
' 2. Decompress
|
|
Dim bFilesDecompressed As Byte() = _compression.Decompress(bFiles)
|
|
' 3. Deserialize
|
|
_files = Deserialize(bFilesDecompressed)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Lädt einen Datei Container aus dem angegebenen Pfad.
|
|
''' Anschließend werden die enthaltenen Dateien entschlüsselt, dekomprimiert und in Files abgelegt.
|
|
''' </summary>
|
|
''' <param name="path">Der Pfad mit Dateiname, von dem der Container geladen wird.</param>
|
|
''' <example>
|
|
''' Public Async Sub foobar()
|
|
''' ...
|
|
''' await container.LoadAsync("container.enc")
|
|
''' Dim files As List(Of FileContainer.FileEntry) = container.Files
|
|
''' ...
|
|
''' End Sub
|
|
''' </example>
|
|
Public Async Function LoadAsync(path As String) As Task
|
|
Dim bFilesEncrypted As Byte() = Await FileToBytesAsync(path)
|
|
|
|
' 1. Decrypt
|
|
Dim bFiles As Byte() = Await _crypto.DecryptAsync(bFilesEncrypted)
|
|
' 2. Decompress
|
|
Dim bFilesDecompressed As Byte() = Await _compression.DecompressAsync(bFiles)
|
|
'Dim bFilesDecompressed = bFiles
|
|
' 3. Deserialize
|
|
_files = Deserialize(bFilesDecompressed)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Fügt einem Datei Container eine neue Datei hinzu
|
|
''' </summary>
|
|
''' <param name="filePath">Der Pfad zur Datei, die im Container gespeichert werden soll</param>
|
|
''' <exception cref="FileNotFoundException" />
|
|
Public Sub AddFile(filePath As String)
|
|
Dim fi As New FileInfo(filePath)
|
|
Dim fe As New FileEntry()
|
|
|
|
If fi.Exists = False Then
|
|
Throw New FileNotFoundException($"{filePath} is not a valid path.")
|
|
End If
|
|
|
|
fe.Contents = IO.File.ReadAllBytes(filePath)
|
|
fe.FileId = Guid.NewGuid().ToString()
|
|
|
|
_files.Add(fe)
|
|
End Sub
|
|
|
|
Public Function GetFile(fileId As String) As FileEntry
|
|
Return _files.Where(Function(f) f.FileId = fileId).FirstOrDefault()
|
|
End Function
|
|
|
|
Private Function Serialize(list As List(Of FileEntry)) As Byte()
|
|
Using ms As New MemoryStream
|
|
_formatter.Serialize(ms, list)
|
|
Return ms.ToArray()
|
|
End Using
|
|
End Function
|
|
|
|
Private Function Deserialize(data As Byte()) As List(Of FileEntry)
|
|
Using ms As New MemoryStream(data)
|
|
Dim list = TryCast(_formatter.Deserialize(ms), List(Of FileEntry))
|
|
Return list
|
|
End Using
|
|
End Function
|
|
|
|
Private Sub BytesToFile(data As Byte(), filePath As String)
|
|
IO.File.WriteAllBytes(filePath, data)
|
|
End Sub
|
|
|
|
Private Function FileToBytes(filePath As String) As Byte()
|
|
Return IO.File.ReadAllBytes(filePath)
|
|
End Function
|
|
|
|
Private Async Function FileToBytesAsync(filePath As String) As Task(Of Byte())
|
|
Using file = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, True)
|
|
Dim buff As Byte() = New Byte(file.Length - 1) {}
|
|
Await file.ReadAsync(buff, 0, file.Length)
|
|
file.Close()
|
|
Return buff
|
|
End Using
|
|
End Function
|
|
|
|
Private Async Sub BytesToFileAsync(data As Byte(), filePath As String)
|
|
Using sourceStream As New FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None, bufferSize:=4096, useAsync:=True)
|
|
Await sourceStream.WriteAsync(data, 0, data.Length)
|
|
End Using
|
|
End Sub
|
|
End Class
|