jj: Add filecontainer
This commit is contained in:
parent
734becb971
commit
4858bb2be5
70
Filesystem/Compression.vb
Normal file
70
Filesystem/Compression.vb
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
Imports System.IO
|
||||||
|
Imports System.IO.Compression
|
||||||
|
Imports DigitalData.Modules.Logging
|
||||||
|
|
||||||
|
Friend Class Compression
|
||||||
|
Private ReadOnly _logger As Logger
|
||||||
|
|
||||||
|
Public Sub New(LogConfig As LogConfig)
|
||||||
|
_logger = LogConfig.GetLogger()
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Async Function CompressAsync(data As Byte()) As Task(Of Byte())
|
||||||
|
Return Await Task.Run(Function() As Byte()
|
||||||
|
Return Compress(data)
|
||||||
|
End Function)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Function Compress(data As Byte()) As Byte()
|
||||||
|
Try
|
||||||
|
' ByteArray in Stream umwandeln
|
||||||
|
Using originalStream As New MemoryStream(data)
|
||||||
|
' Ziel Stream erstellen
|
||||||
|
Using compressedStream As New MemoryStream()
|
||||||
|
' Gzip-Stream erstellen, der alle Daten komprimiert und zu compressedStream durchleitet
|
||||||
|
'
|
||||||
|
' > MemoryStream > GzipStream > MemoryStream
|
||||||
|
' originalStream --> compressionStream --> compressedFileStream
|
||||||
|
'
|
||||||
|
Using compressionStream As New GZipStream(compressedStream, CompressionMode.Compress)
|
||||||
|
originalStream.CopyTo(compressionStream)
|
||||||
|
compressionStream.Close()
|
||||||
|
Return compressedStream.ToArray()
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Async Function DecompressAsync(data As Byte()) As Task(Of Byte())
|
||||||
|
Return Await Task.Run(Function() As Byte()
|
||||||
|
Return Decompress(data)
|
||||||
|
End Function)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Function Decompress(data As Byte()) As Byte()
|
||||||
|
Try
|
||||||
|
' ByteArray in Stream umwandeln
|
||||||
|
Using compressedStream As New MemoryStream(data)
|
||||||
|
' Ziel Stream erstellen
|
||||||
|
Using decompressedStream As New MemoryStream()
|
||||||
|
' Gzip-Stream erstellen, der alle Daten komprimiert und zu compressedStream durchleitet
|
||||||
|
'
|
||||||
|
' > MemoryStream > GzipStream > MemoryStream
|
||||||
|
' compressedStream --> decompressionStream --> decompressedStream
|
||||||
|
'
|
||||||
|
Using decompressionStream As New GZipStream(compressedStream, CompressionMode.Decompress)
|
||||||
|
decompressionStream.CopyTo(decompressedStream)
|
||||||
|
Return decompressedStream.ToArray()
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
119
Filesystem/Encryption.vb
Normal file
119
Filesystem/Encryption.vb
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
Imports System.IO
|
||||||
|
Imports System.Security.Cryptography
|
||||||
|
Imports DigitalData.Modules.Logging
|
||||||
|
|
||||||
|
''' <summary>
|
||||||
|
''' https://stackoverflow.com/questions/10168240/encrypting-decrypting-a-string-in-c-sharp
|
||||||
|
''' </summary>
|
||||||
|
Friend Class Encryption
|
||||||
|
' This constant is used to determine the keysize of the encryption algorithm in bits.
|
||||||
|
' We divide this by 8 within the code below to get the equivalent number of bytes.
|
||||||
|
Private Const KEYSIZE As Integer = 256
|
||||||
|
' This constant determines the number of iterations for the password bytes generation function.
|
||||||
|
Private Const DERIVATION_ITERATIONS As Integer = 1000
|
||||||
|
Private ReadOnly _password As String
|
||||||
|
Private _logger As Logger
|
||||||
|
|
||||||
|
Public Sub New(LogConfig As LogConfig, Password As String)
|
||||||
|
_logger = LogConfig.GetLogger()
|
||||||
|
|
||||||
|
If IsNothing(Password) Then
|
||||||
|
Throw New ArgumentNullException("Password")
|
||||||
|
End If
|
||||||
|
|
||||||
|
_password = Password
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Async Function EncryptAsync(oPlainTextBytes As Byte()) As Task(Of Byte())
|
||||||
|
Return Await Task.Run(Function() As Byte()
|
||||||
|
Return Encrypt(oPlainTextBytes)
|
||||||
|
End Function)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Function Encrypt(oPlainTextBytes As Byte()) As Byte()
|
||||||
|
Try
|
||||||
|
' Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
|
||||||
|
' so that the same Salt and IV values can be used when decrypting.
|
||||||
|
Dim oSaltStringBytes = Generate256BitsOfRandomEntropy()
|
||||||
|
Dim oIvStringBytes = Generate256BitsOfRandomEntropy()
|
||||||
|
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
||||||
|
Dim oKeyBytes = oPassword.GetBytes(KEYSIZE / 8)
|
||||||
|
Using oSymmetricKey = New RijndaelManaged()
|
||||||
|
oSymmetricKey.BlockSize = 256
|
||||||
|
oSymmetricKey.Mode = CipherMode.CBC
|
||||||
|
oSymmetricKey.Padding = PaddingMode.PKCS7
|
||||||
|
Using oEncryptor = oSymmetricKey.CreateEncryptor(oKeyBytes, oIvStringBytes)
|
||||||
|
Using oMemoryStream = New MemoryStream()
|
||||||
|
Using oCryptoStream = New CryptoStream(oMemoryStream, oEncryptor, CryptoStreamMode.Write)
|
||||||
|
oCryptoStream.Write(oPlainTextBytes, 0, oPlainTextBytes.Length)
|
||||||
|
oCryptoStream.FlushFinalBlock()
|
||||||
|
' Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
|
||||||
|
Dim oCipherTextBytes = oSaltStringBytes
|
||||||
|
oCipherTextBytes = oCipherTextBytes.Concat(oIvStringBytes).ToArray()
|
||||||
|
oCipherTextBytes = oCipherTextBytes.Concat(oMemoryStream.ToArray()).ToArray()
|
||||||
|
oMemoryStream.Close()
|
||||||
|
oCryptoStream.Close()
|
||||||
|
Return oCipherTextBytes
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Async Function DecryptAsync(CipherTextBytesWithSaltAndIv As Byte()) As Task(Of Byte())
|
||||||
|
Return Await Task.Run(Function() As Byte()
|
||||||
|
Return Decrypt(CipherTextBytesWithSaltAndIv)
|
||||||
|
End Function)
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Public Function Decrypt(cipherTextBytesWithSaltAndIv As Byte()) As Byte()
|
||||||
|
Try
|
||||||
|
' Get the complete stream of bytes that represent:
|
||||||
|
' [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
|
||||||
|
' Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
|
||||||
|
Dim oSaltStringBytes = cipherTextBytesWithSaltAndIv.Take(KEYSIZE / 8).ToArray()
|
||||||
|
' Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
|
||||||
|
Dim oIvStringBytes = cipherTextBytesWithSaltAndIv.Skip(KEYSIZE / 8).Take(KEYSIZE / 8).ToArray()
|
||||||
|
' Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
|
||||||
|
Dim oCipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((KEYSIZE / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((KEYSIZE / 8) * 2)).ToArray()
|
||||||
|
|
||||||
|
Using oPassword = New Rfc2898DeriveBytes(_password, oSaltStringBytes, DERIVATION_ITERATIONS)
|
||||||
|
Dim oKeyBytes = oPassword.GetBytes(KEYSIZE / 8)
|
||||||
|
Using oSymmetricKey = New RijndaelManaged()
|
||||||
|
oSymmetricKey.BlockSize = 256
|
||||||
|
oSymmetricKey.Mode = CipherMode.CBC
|
||||||
|
oSymmetricKey.Padding = PaddingMode.PKCS7
|
||||||
|
Using oDecryptor = oSymmetricKey.CreateDecryptor(oKeyBytes, oIvStringBytes)
|
||||||
|
Using oMemoryStream = New MemoryStream(oCipherTextBytes)
|
||||||
|
Using oCryptoStream = New CryptoStream(oMemoryStream, oDecryptor, CryptoStreamMode.Read)
|
||||||
|
Dim oPlainTextBytes = New Byte(oCipherTextBytes.Length - 1) {}
|
||||||
|
Dim oDecryptedByteCount = oCryptoStream.Read(oPlainTextBytes, 0, oPlainTextBytes.Length)
|
||||||
|
oMemoryStream.Close()
|
||||||
|
oCryptoStream.Close()
|
||||||
|
Return oPlainTextBytes
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
End Using
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Shared Function Generate256BitsOfRandomEntropy() As Byte()
|
||||||
|
Dim oRandomBytes = New Byte(31) {}
|
||||||
|
' 32 Bytes will give us 256 bits.
|
||||||
|
Using oRNGCsp = New RNGCryptoServiceProvider()
|
||||||
|
' Fill the array with cryptographically secure random bytes.
|
||||||
|
oRNGCsp.GetBytes(oRandomBytes)
|
||||||
|
End Using
|
||||||
|
Return oRandomBytes
|
||||||
|
End Function
|
||||||
|
End Class
|
||||||
284
Filesystem/FileContainer.vb
Normal file
284
Filesystem/FileContainer.vb
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
Imports System.IO
|
||||||
|
Imports System.Runtime.Serialization.Formatters.Binary
|
||||||
|
Imports DigitalData.Modules.Logging
|
||||||
|
|
||||||
|
''' <module>FileContainer</module>
|
||||||
|
''' <version>0.0.0.1</version>
|
||||||
|
''' <date>16.11.2018</date>
|
||||||
|
''' <summary>
|
||||||
|
''' File Container for securely saving files
|
||||||
|
''' </summary>
|
||||||
|
''' <dependencies>
|
||||||
|
''' NLog, >= 4.5.8
|
||||||
|
''' </dependencies>
|
||||||
|
''' <params>
|
||||||
|
''' LogConfig, DigitalData.Module.Logging.LogConfig
|
||||||
|
''' A LogConfig object
|
||||||
|
''' </params>
|
||||||
|
''' <props>
|
||||||
|
''' </props>
|
||||||
|
''' <example>
|
||||||
|
''' </example>
|
||||||
|
''' <remarks>
|
||||||
|
''' </remarks>
|
||||||
|
Public Class FileContainer
|
||||||
|
Private _files As List(Of FileEntry)
|
||||||
|
Private _crypto As Encryption
|
||||||
|
Private _compression As Compression
|
||||||
|
Private _formatter As BinaryFormatter
|
||||||
|
Private _containerId As Guid
|
||||||
|
Private _inner As FileContainerInner
|
||||||
|
Private _logger As Logger
|
||||||
|
Private _logConfig As LogConfig
|
||||||
|
|
||||||
|
<Serializable>
|
||||||
|
Public Class FileEntry
|
||||||
|
Public FileId As String
|
||||||
|
Public Contents As Byte()
|
||||||
|
Public CreatedAt As DateTime
|
||||||
|
Public UpdatedAt As DateTime
|
||||||
|
End Class
|
||||||
|
|
||||||
|
<Serializable>
|
||||||
|
Public Class FileContainerInner
|
||||||
|
Public Files As List(Of FileEntry)
|
||||||
|
Public ContainerID As Guid
|
||||||
|
Public CreatedAt As DateTime
|
||||||
|
Public UpdatedAt As DateTime
|
||||||
|
End Class
|
||||||
|
|
||||||
|
Public ReadOnly Property ContainerId As String
|
||||||
|
Get
|
||||||
|
If _inner Is Nothing Then
|
||||||
|
Return Nothing
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return _inner.ContainerID.ToString
|
||||||
|
End Get
|
||||||
|
End Property
|
||||||
|
|
||||||
|
|
||||||
|
''' <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
|
||||||
|
If _inner Is Nothing Then
|
||||||
|
Return Nothing
|
||||||
|
End If
|
||||||
|
|
||||||
|
Return _inner.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(LogConfig As LogConfig, Password As String)
|
||||||
|
_logger = LogConfig.GetLogger()
|
||||||
|
_crypto = New Encryption(LogConfig, Password)
|
||||||
|
_compression = New Compression(LogConfig)
|
||||||
|
_formatter = New BinaryFormatter
|
||||||
|
_inner = New FileContainerInner() With {
|
||||||
|
.Files = New List(Of FileEntry),
|
||||||
|
.ContainerID = Guid.NewGuid(),
|
||||||
|
.CreatedAt = New DateTime()
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
Try
|
||||||
|
' 1. Serialize
|
||||||
|
Dim oFileContainerInner As Byte() = Serialize(_inner)
|
||||||
|
' 2. Compress
|
||||||
|
Dim oFileContainerCompressed As Byte() = _compression.Compress(oFileContainerInner)
|
||||||
|
' 3. Encrypt
|
||||||
|
Dim oFileContainerEncrypted As Byte() = _crypto.Encrypt(oFileContainerCompressed)
|
||||||
|
|
||||||
|
BytesToFile(oFileContainerEncrypted, Path)
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
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
|
||||||
|
Try
|
||||||
|
' 1. Serialize
|
||||||
|
Dim oFileContainerInner As Byte() = Serialize(_inner)
|
||||||
|
' 2. Compress
|
||||||
|
Dim oFileContainerCompressed As Byte() = Await _compression.CompressAsync(oFileContainerInner)
|
||||||
|
'Dim bFilesCompressed = bFiles
|
||||||
|
' 3. Encrypt
|
||||||
|
Dim oFileContainerEncrypted As Byte() = Await _crypto.EncryptAsync(oFileContainerCompressed)
|
||||||
|
|
||||||
|
BytesToFileAsync(oFileContainerEncrypted, Path)
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
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)
|
||||||
|
Try
|
||||||
|
Dim oContainerInnerEncrypted As Byte() = FileToBytes(Path)
|
||||||
|
|
||||||
|
' 1. Decrypt
|
||||||
|
Dim oFileContainerCompressed As Byte() = _crypto.Decrypt(oContainerInnerEncrypted)
|
||||||
|
' 2. Decompress
|
||||||
|
Dim oFileContainerInner As Byte() = _compression.Decompress(oFileContainerCompressed)
|
||||||
|
' 3. Deserialize
|
||||||
|
|
||||||
|
_inner = Deserialize(oFileContainerInner)
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
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
|
||||||
|
Try
|
||||||
|
Dim oContainerInnerEncrypted As Byte() = Await FileToBytesAsync(Path)
|
||||||
|
|
||||||
|
' 1. Decrypt
|
||||||
|
Dim oFileContainerCompressed As Byte() = Await _crypto.DecryptAsync(oContainerInnerEncrypted)
|
||||||
|
' 2. Decompress
|
||||||
|
Dim oFileContainerInner As Byte() = Await _compression.DecompressAsync(oFileContainerCompressed)
|
||||||
|
' 3. Deserialize
|
||||||
|
_inner = Deserialize(oFileContainerInner)
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
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)
|
||||||
|
Try
|
||||||
|
Dim oFileInfo As New FileInfo(FilePath)
|
||||||
|
|
||||||
|
If oFileInfo.Exists = False Then
|
||||||
|
Throw New FileNotFoundException($"{FilePath} is not a valid path.")
|
||||||
|
End If
|
||||||
|
|
||||||
|
AddFile(IO.File.ReadAllBytes(FilePath))
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Sub AddFile(FileContents As Byte())
|
||||||
|
Try
|
||||||
|
Dim oFileEntry As New FileEntry With {
|
||||||
|
.Contents = FileContents,
|
||||||
|
.FileId = Guid.NewGuid().ToString()
|
||||||
|
}
|
||||||
|
|
||||||
|
_inner.Files.Add(oFileEntry)
|
||||||
|
Catch ex As Exception
|
||||||
|
_logger.Error(ex)
|
||||||
|
Throw ex
|
||||||
|
End Try
|
||||||
|
End Sub
|
||||||
|
|
||||||
|
Public Function GetFile(FileId As String) As FileEntry
|
||||||
|
Return _inner.Files.Where(Function(f) f.FileId = FileId).FirstOrDefault()
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function Serialize(InnerData As FileContainerInner) As Byte()
|
||||||
|
Using oStream As New MemoryStream
|
||||||
|
_formatter.Serialize(oStream, InnerData)
|
||||||
|
Return oStream.ToArray()
|
||||||
|
End Using
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Function Deserialize(InnerData As Byte()) As FileContainerInner
|
||||||
|
Using oStream As New MemoryStream(InnerData)
|
||||||
|
Dim oInner = TryCast(_formatter.Deserialize(oStream), FileContainerInner)
|
||||||
|
Return oInner
|
||||||
|
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 oFileStream = New FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, True)
|
||||||
|
Dim oBuffer As Byte() = New Byte(oFileStream.Length - 1) {}
|
||||||
|
Await oFileStream.ReadAsync(oBuffer, 0, oFileStream.Length)
|
||||||
|
oFileStream.Close()
|
||||||
|
Return oBuffer
|
||||||
|
End Using
|
||||||
|
End Function
|
||||||
|
|
||||||
|
Private Async Sub BytesToFileAsync(Data As Byte(), FilePath As String)
|
||||||
|
Using oSourceStream As New FileStream(FilePath, FileMode.Append, FileAccess.Write, FileShare.None, bufferSize:=4096, useAsync:=True)
|
||||||
|
Await oSourceStream.WriteAsync(Data, 0, Data.Length)
|
||||||
|
End Using
|
||||||
|
End Sub
|
||||||
|
End Class
|
||||||
@ -72,7 +72,10 @@
|
|||||||
<Import Include="System.Threading.Tasks" />
|
<Import Include="System.Threading.Tasks" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Compression.vb" />
|
||||||
|
<Compile Include="Encryption.vb" />
|
||||||
<Compile Include="File.vb" />
|
<Compile Include="File.vb" />
|
||||||
|
<Compile Include="FileContainer.vb" />
|
||||||
<Compile Include="My Project\AssemblyInfo.vb" />
|
<Compile Include="My Project\AssemblyInfo.vb" />
|
||||||
<Compile Include="My Project\Application.Designer.vb">
|
<Compile Include="My Project\Application.Designer.vb">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user