/// <summary> /// Saves a file to storage for a tenant in the specified container /// </summary> public virtual bool SaveFile(Guid tenantId, string container, string fileName) { try { long fileLength = 0; DateTime creationTime = DateTime.Now; DateTime lastWriteTime = DateTime.Now; if (fileName.Length > 260) { NativeMethods.GetFileInfo(fileName, out creationTime, out lastWriteTime, out fileLength); } else { var fi = new FileInfo(fileName); fileLength = fi.Length; creationTime = fi.CreationTime; lastWriteTime = fi.LastWriteTime; } //Save the file const int blockSize = 1024 * 1024; var count = (int)Math.Ceiling((fileLength * 1.0) / blockSize); var block = new FileInformation { Container = container, FileName = fileName, TenantID = tenantId, CRC = FileUtilities.FileCRC(fileName), Size = fileLength, CreatedTime = creationTime.ToUniversalTime(), ModifiedTime = lastWriteTime.ToUniversalTime(), }; //using (var fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var fs = LongFile.GetFileStream(fileName, FileAccess.ReadWrite)) { FileDataInfo fileInfo = null; RetryHelper.DefaultRetryPolicy(3) .Execute(() => { using (var factory = GetFactory(_server, _port)) { var service = factory.CreateChannel(); fileInfo = service.SendFileStart(block); } }); for (var ii = 0; ii < count; ii++) { var bb = new byte[blockSize]; var c = fs.Read(bb, 0, bb.Length); //If last block is smaller then truncate it if (c < blockSize) { bb = bb.Take(c).ToArray(); } RetryHelper.DefaultRetryPolicy(3) .Execute(() => { using (var factory = GetFactory(_server, _port)) { var service = factory.CreateChannel(); var wasSaved = service.SendFileData(fileInfo.Token, bb, ii); } }); this.OnFileUpload(new FileProgressEventArgs { ChunkIndex = ii, Container = container, FileName = fileName, TotalChunks = count, }); } var retval = false; RetryHelper.DefaultRetryPolicy(3) .Execute(() => { using (var factory = GetFactory(_server, _port)) { var service = factory.CreateChannel(); retval = service.SendFileEnd(fileInfo.Token); } }); return(retval); } } catch (Exception ex) { throw; } }
/// <summary> /// Get a file from storage for a tenant in the specified container /// </summary> public virtual OutfileItem GetFile(Guid tenantId, string container, string fileName) { try { FileDataInfo fileInfo = null; RetryHelper.DefaultRetryPolicy(3) .Execute(() => { using (var factory = GetFactory(_server, _port)) { var service = factory.CreateChannel(); fileInfo = service.GetFileStart(tenantId, container, fileName); } }); if (fileInfo.Token == Guid.Empty) { return(null); } var index = 0; var count = 0; var tempfile = Path.Combine(this.WorkingFolder, Guid.NewGuid().ToString()); var aes = FileUtilities.CryptoProvider(FileUtilities.GenerateKey(), FileUtilities.GenerateIV()); var newfs = File.Create(tempfile); using (var cryptoStream = new CryptoStream(newfs, aes.CreateEncryptor(), CryptoStreamMode.Write)) { do { count = 0; byte[] arr = null; RetryHelper.DefaultRetryPolicy(3) .Execute(() => { using (var factory = GetFactory(_server, _port)) { var service = factory.CreateChannel(); arr = service.GetFilePart(fileInfo.Token, index); if (arr != null) { this.OnFileDownload(new FileProgressEventArgs { ChunkIndex = index, Container = container, FileName = fileName, TotalChunks = count, }); } } }); if (arr != null) { count = arr.Length; cryptoStream.Write(arr, 0, arr.Length); } index++; } while (count > 0); } newfs = File.OpenRead(tempfile); var outStream = new CryptoStream(newfs, aes.CreateDecryptor(), CryptoStreamMode.Read); return(new OutfileItem { EncryptedFileName = tempfile, EncryptedStream = outStream, WorkingFolder = this.WorkingFolder, }); } catch (Exception ex) { throw; } }