//private static void CheckVolume(string targetPath, byte[] result, int volumnSize,string extension,bool coverExisted ref string encryptedFileName, ref int fileCount, ref FileStream fsnew, ref long currentSize) //{ //} public static FileInfo[] DecryptFile(this RijndaelManaged manager, string sourcePath, string targetPath, int bufferLength = 1024 * 1024, string suffix = null, bool coverExistedFile = false, RefreshFileProgress refreshFileProgress = null) { string target = targetPath.RemoveEnd(suffix); CheckFileAndDirectoryExist(target, coverExistedFile); List <string> encryptedFileNames = new List <string>() { sourcePath }; var lastencryptedFile = sourcePath; try { int fileCount = 0; while (File.Exists(sourcePath + (++fileCount))) { encryptedFileNames.Add(sourcePath + fileCount); lastencryptedFile = sourcePath + fileCount; } using (FileStream streamTarget = new FileStream(target, FileMode.OpenOrCreate, FileAccess.Write)) { using (var decryptor = manager.CreateDecryptor()) { foreach (var encryptedFileName in encryptedFileNames) { FileStream streamSource = new FileStream(encryptedFileName, FileMode.Open, FileAccess.Read); long currentSize = 0; int size; byte[] input = new byte[bufferLength]; byte[] output = new byte[bufferLength]; long fileLength = streamSource.Length; while ((size = streamSource.Read(input, 0, input.Length)) != 0) { int outputSize = 0; if (streamSource.Position == fileLength && encryptedFileName == lastencryptedFile) { outputSize = (output = decryptor.TransformFinalBlock(input, 0, size)).Length; } else { outputSize = decryptor.TransformBlock(input, 0, size, output, 0); } currentSize += output.Length; streamTarget.Write(output, 0, outputSize); streamTarget.Flush(); refreshFileProgress?.Invoke(sourcePath, encryptedFileName, fileLength, currentSize); //更新进度 } streamSource.Close(); streamSource.Dispose(); } } streamTarget.Close(); streamTarget.Dispose(); } new FileInfo(target).Attributes = File.GetAttributes(sourcePath); return(encryptedFileNames.Select(p => new FileInfo(p)).ToArray()); } catch (Exception ex) { HandleException(target, ex); return(null); } }
/// <summary> /// 加密文件 /// </summary> /// <param name="manager"></param> /// <param name="sourcePath">源文件地址</param> /// <param name="targetPath">目标文件地址</param> /// <param name="bufferLength">缓冲区大小</param> /// <param name="suffix">加密后的文件后缀</param> /// <param name="volumeSize">分卷大小,0表示不分卷</param> /// <param name="coverExistedFile">是否覆盖已存在文件。若为False但存在文件,则会抛出异常</param> /// <param name="refreshFileProgress"></param> /// <returns></returns> public static FileInfo EncryptFile(this RijndaelManaged manager, string sourcePath, string targetPath, int bufferLength = 1024 * 1024, string suffix = null, int volumeSize = 0, bool coverExistedFile = false, RefreshFileProgress refreshFileProgress = null) { if (volumeSize < 0) { throw new ArgumentOutOfRangeException(nameof(volumeSize), "分卷大小不可小于0"); } if (string.IsNullOrEmpty(suffix) && volumeSize > 0) { throw new ArgumentException("加密文件扩展名为空和分卷加密不可同时存在"); } if (suffix == null) { suffix = ""; } string encryptedFileName = targetPath + suffix; CheckFileAndDirectoryExist(encryptedFileName, coverExistedFile); int fileCount = 0; try { using (FileStream streamSource = new FileStream(sourcePath, FileMode.Open, FileAccess.Read)) { FileStream streamTarget = new FileStream(encryptedFileName, FileMode.OpenOrCreate, FileAccess.Write); using (var encryptor = manager.CreateEncryptor()) { long currentSize = 0; int size; byte[] input = new byte[bufferLength]; byte[] output = new byte[bufferLength]; long fileLength = streamSource.Length; while ((size = streamSource.Read(input, 0, bufferLength)) != 0) { if (streamSource.Position == fileLength) { output = encryptor.TransformFinalBlock(input, 0, size); } else { encryptor.TransformBlock(input, 0, size, output, 0); } currentSize += size; if (volumeSize != 0 && currentSize > volumeSize) { streamTarget.Close(); streamTarget.Dispose(); currentSize = output.Length; fileCount++; encryptedFileName = targetPath + suffix + fileCount; CheckFileAndDirectoryExist(encryptedFileName, coverExistedFile); streamTarget = new FileStream(encryptedFileName, FileMode.OpenOrCreate, FileAccess.Write); } streamTarget.Write(output, 0, output.Length); streamTarget.Flush(); refreshFileProgress?.Invoke(sourcePath, encryptedFileName, fileLength, currentSize); //更新进度 } streamTarget.Close(); streamTarget.Dispose(); } } FileInfo encryptedFile = new FileInfo(targetPath + suffix); encryptedFile.Attributes = File.GetAttributes(sourcePath); return(encryptedFile); } catch (Exception ex) { HandleException(sourcePath, encryptedFileName, fileCount, ex, suffix); return(null); } }