我有一个inputStream
,我想用它来计算散列,将文件保存到磁盘。 我想知道如何有效地做到这一点。 我应该使用一些任务,这样做的同时,我要重复的流通到两个流,一个是在saveFile
方法,一个用于computeHash
方法,或者我应该做点别的?
Answer 1:
什么使用上的块级操作的哈希算法? 您可以将块添加到哈希(使用TransformBlock),随后写了块流中的文件的foreach块。
未经测试的粗糙的镜头:
using System.IO;
using System.Security.Cryptography;
...
public byte[] HashedFileWrite(string filename, Stream input)
{
var hash_algorithm = MD5.Create();
using(var file = File.OpenWrite(filename))
{
byte[] buffer = new byte[4096];
int read = 0;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
hash_algorithm.TransformBlock(buffer, 0, read, null, 0);
file.Write(buffer, 0, read);
}
hash_algorithm.TransformFinalBlock(buffer, 0, read);
}
return hash_algorithm.Hash;
}
Answer 2:
此方法将复制与链接流的哈希。
private static byte[] CopyAndHash(string source, string target, Action<double> progress, Func<bool> isCanceled)
{
using(var sha512 = SHA512.Create())
using (var targetStream = File.OpenWrite(target))
using (var cryptoStream = new CryptoStream(targetStream, sha512, CryptoStreamMode.Write))
using (var sourceStream = File.OpenRead(source))
{
byte[] buffer = new byte[81920];
int read;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0 && !isCanceled())
{
cryptoStream.Write(buffer, 0, read);
progress?.Invoke((double) sourceStream.Length / sourceStream.Position * 100);
}
File.SetAttributes(target, File.GetAttributes(source));
return sha512.Hash;
}
}
全部样本看https://gist.github.com/dhcgn/da1637277d9456db9523a96a0a34da78
Answer 3:
它可能不是最好的选择,但我会选择去Stream
后裔/包装,一个将被传递通过一个实际写入文件到磁盘。
所以:
- 从获得
Stream
- 有一个构件,如
Stream _inner;
这将是写目标流 - 实现
Write()
和所有相关的东西 - 在
Write()
散列的数据块,并调用_inner.Write()
用法示例
Stream s = File.Open("infile.dat");
Stream out = File.Create("outfile.dat");
HashWrapStream hasher = new HashWrapStream(out);
byte[] buffer=new byte[1024];
int read = 0;
while ((read=s.Read(buffer)!=0)
{
hasher.Write(buffer);
}
long hash=hasher.GetComputedHash(); // get actual hash
hasher.Dispose();
s.Dispose();
Answer 4:
你需要的东西流的字节到一个byte[]
以哈希他们。
Answer 5:
这是我的溶液,将其写入结构的数组(蜱变量),为csv文件(使用CsvHelper NuGet包),并随后创建用于使用后缀.sha256校验目的的散列
我写的CSV到一个MemoryStream,然后写入内存流到磁盘,然后将MemoryStream传递给哈希算法中做到这一点。
该解决方案是围绕保持整个文件作为一个MemoryStream。 这是罚款,除了会跑,你出柱塞的多千兆字节的文件的一切。 如果我不得不再次做到这一点,我可能会尝试使用CryptoStream的方法,但是这是我的预见已经足够了。
我已经通过第三方工具,哈希值是有效的验证。
下面是代码:
//var ticks = **some_array_you_want_to_write_as_csv**
using (var memoryStream = new System.IO.MemoryStream())
{
using (var textWriter = new System.IO.StreamWriter(memoryStream))
{
using (var csv = new CsvHelper.CsvWriter(textWriter))
{
csv.Configuration.DetectColumnCountChanges = true; //error checking
csv.Configuration.RegisterClassMap<TickDataClassMap>();
csv.WriteRecords(ticks);
textWriter.Flush();
//write to disk
using (var fileStream = new System.IO.FileStream(targetFileName, System.IO.FileMode.Create))
{
memoryStream.Position = 0;
memoryStream.CopyTo(fileStream);
}
//write sha256 hash, ensuring that the file was properly written
using (var sha256 = System.Security.Cryptography.SHA256.Create())
{
memoryStream.Position = 0;
var hash = sha256.ComputeHash(memoryStream);
using (var reader = System.IO.File.OpenRead(targetFileName))
{
System.IO.File.WriteAllText(targetFileName + ".sha256", hash.ConvertByteArrayToHexString());
}
}
}
}
}
文章来源: Computing Hash while saving a file?