web-dev-qa-db-ja.com

C#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の計算をコメントアウトすると、ファイルが削除されてコードが実行されるため、ComputeHash(fs)と関係があるように見えます。

12
mattdwen

私はあなたのコードをコンソールアプリに入れてエラーなしで実行し、ハッシュを取得し、実行の最後にテストファイルを削除しましたか?テストアプリの.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;
        }
    }
}
15
Brian ONeil

名前空間をインポートする

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();
}
20
Sharp Coders

MD5オブジェクトをusing()でラップしてみましたか?ドキュメントから、MD5は使い捨てです。それはそれがファイルを手放すかもしれません。

1
Moose

md5hasher.Clear() ループがうまくいくかもしれない後。

0
JP Alioto