I need to ZIP and GPG Encrypt a Stream of files. Then upload via SFTP. I am using Zip Archive to create entries. I am using GPG to encrypt, starksoft.aspen Nuget.
Getting local file streams here and returning an I Enumerable of local file streams
private static IEnumerable<LocalFile> GetLocalFiles(string dir) =>
Directory.EnumerateFiles(dir, "*", SearchOption.AllDirectories)
.Select(path =>
{
var relativePath = path.Substring(dir.Length + 1);
var localFile = new LocalFile(relativePath, () => File.OpenRead(path));
localFile.Folder = Directory.GetDirectories(dir, "*", SearchOption.TopDirectoryOnly)
.Select(d => d.Split('\\').LastOrDefault()).FirstOrDefault();
return localFile;
});
Then I zip the IEnumerable of local streams
public async Task WriteAsync(IEnumerable<LocalFile> files)
{
FileStream GetTempFileStream() =>
new FileStream(
path: Path.GetTempFileName(),
mode: FileMode.Open,
access: FileAccess.ReadWrite,
share: FileShare.None,
bufferSize: 4096,
options: FileOptions.DeleteOnClose);
//temp fix to resolve the arb naming for zip files
var folder = files.Select(x => x.Folder).FirstOrDefault()
?? DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss");
var zipFile = new LocalFile(
folder+".zip",
async () =>
{
var tempFileStream = GetTempFileStream();
using (var archive = new ZipArchive(tempFileStream, ZipArchiveMode.Create, true))
{
foreach (var file in files)
{
using (var localStream = (await file.OpenLocal()))
using (var zipEntryStream = archive.CreateEntry(file.RelativePath).Open())
{
await localStream.CopyToAsync(zipEntryStream);
}
}
}
tempFileStream.Seek(0, SeekOrigin.Begin);
return tempFileStream;
});
Then I need to encrypt the IEnumerable of zip stream...
got to the bottom of this The problem I had was the stream was not done encrypting before being passed by to my Writer.
Here is what I did to zip and encrypt , I hope this helps someone
public async Task WriteAsync(IEnumerable<LocalFile> files)
{
var folder = files.Select(x => x.Folder).FirstOrDefault()
?? DateTime.Now.ToString("yyyy-MM-dd hh-mm-ss");
using (var archiveStream = new MemoryStream())
{
using (var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true))
{
foreach (var file in files)
{
using (var entry = archive.CreateEntry(file.RelativePath).Open())
using (var local = (await file.OpenLocal()))
{
local.CopyTo(entry);
}
}
}
var bytes = archiveStream.ToArray();
var encryptionClient = new EncryptionClient("[email protected]", "Password7");
var encryption = new EncryptFiles(encryptionClient);
using (var encryptedStream = new MemoryStream())
{
using (var zipStream = new MemoryStream(bytes))
{
encryption.Gpg.Encrypt(zipStream, encryptedStream);
}
this.bytesArr = encryptedStream.ToArray();
}
}
await this.Writer.WriteAsync(new[] { new LocalFile(folder + ".zip.gpg", () => new MemoryStream(this.bytesArr)) });