Пример хеширования С# MD5
Изменить: Я переименовал это в пример, поскольку код работает так, как ожидалось.
Я пытаюсь скопировать файл, получить хеш MD5, а затем удалить копию. Я делаю это, чтобы избежать блокировок процесса в исходном файле, к которому пишет другое приложение. Тем не менее, я получаю блокировку файла, который я скопировал.
File.Copy(pathSrc, pathDest, true);
String md5Result;
StringBuilder sb = new StringBuilder();
MD5 md5Hasher = MD5.Create();
using (FileStream fs = File.OpenRead(pathDest))
{
foreach(Byte b in md5Hasher.ComputeHash(fs))
sb.Append(b.ToString("x2").ToLower());
}
md5Result = sb.ToString();
File.Delete(pathDest);
Затем я получаю исключение "процесс не может получить доступ к файлу" на File.Delete()
".
Я бы ожидал, что с помощью оператора using
поток будет закрыт красиво. Я также попробовал объявить отдельный поток, удалив using
и положив fs.Close()
и fs.Dispose()
после чтения.
После этого я прокомментировал фактическое вычисление md5, и код excutes, с удаляемым файлом, поэтому похоже, что это что-то связано с ComputeHash(fs)
.
Ответы
Ответ 1
Я взял ваш код в консольное приложение и запустил его без ошибок, получил хэш и тестовый файл был удален в конце выполнения? Я просто использовал .pdb из моего тестового приложения в качестве файла.
Какую версию .NET вы используете?
Я помещаю код, который у меня есть, который работает здесь, и если вы поместите его в консольное приложение в VS2008.NET 3.5 sp1, оно будет работать без ошибок (по крайней мере для меня).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace lockTest
{
class Program
{
static void Main(string[] args)
{
string hash = GetHash("lockTest.pdb");
Console.WriteLine("Hash: {0}", hash);
Console.ReadKey();
}
public static string GetHash(string pathSrc)
{
string pathDest = "copy_" + pathSrc;
File.Copy(pathSrc, pathDest, true);
String md5Result;
StringBuilder sb = new StringBuilder();
MD5 md5Hasher = MD5.Create();
using (FileStream fs = File.OpenRead(pathDest))
{
foreach (Byte b in md5Hasher.ComputeHash(fs))
sb.Append(b.ToString("x2").ToLower());
}
md5Result = sb.ToString();
File.Delete(pathDest);
return md5Result;
}
}
}
Ответ 2
Импортировать пространство имен
using System.Security.Cryptography;
Вот функция, возвращающая хэш-код md5. Вам нужно передать строку как параметр.
public static string GetMd5Hash(string input)
{
MD5 md5Hash = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
Ответ 3
Вы пытались обернуть свой объект MD5 в use() тоже? Из документов MD5 является одноразовым. Это может заставить его отпустить файл.
Ответ 4
md5hasher.Clear() после того, как ваш цикл может сделать трюк.
Ответ 5
Вы пытались установить md5Hasher на null перед удалением файла? Вероятно, у него есть дескриптор, прикрепленный к FileStream (возможно, утечка памяти).
Ответ 6
Почему бы не открыть файл с помощью FileShare.ReadWrite?