2009-05-06 15 views
12

Düzenleme: Kodun beklendiği gibi çalıştığından bunu bir örneğe aldım.C# MD5 hasher örneği

Bir dosyayı kopyalamaya çalışıyorum, bir MD5 hash olsun, sonra da kopyayı silin. Başka bir uygulamanın yazdığı orijinal dosyada işlem kilitlerini önlemek için bunu yapıyorum. Ancak, kopyaladığım dosyada bir kilit alıyorum.

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); 

Sonra 'bir File.Delete() üzerinde istisna 'süreç dosyası erişemiyor' alıyorum.

using deyimiyle, filestream güzelce kapatılmış olur. Ayrıca filestream'i ayrı ayrı ilan etmeyi, using'u kaldırmayı ve okunduktan sonra fs.Close() ve fs.Dispose()'u koymayı denedim.

Bundan sonra, aslında md5 hesaplamasını ve kod silinmesini, dosyanın silinmesiyle yorumladım, bu yüzden ComputeHash(fs) ile ilgili bir şey gibi görünüyor.

+1

Neden sadece ReadAllBytes() yöntemini çağırıyor ve bununla bitmiyor? – BobbyShaftoe

+1

ComputeHash çağrısı bir akışta çalışır, çünkü dosya büyükse, bellekte kalması gerekmez. –

+0

Dosyayı silmeden önce kapatmak zorunda değil misiniz? – JonnyBoats

cevap

15

Kodunuzu bir konsol uygulamasına aldım ve hiçbir hata olmadan çalıştırdım, karma aldım ve test dosyası yürütme sonunda silindi mi? Ben sadece test uygulamasından .pdb dosyasını dosya olarak kullandım.

Hangi .NET sürümünü kullanıyorsunuz?

Burada çalıştığım kodu koyuyor ve bunu VS2008 .NET 3.5 sp1 uygulamasında bir konsol uygulamasına koyarsanız hata içermiyor (en azından benim için).

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; 
     } 
    } 
} 
+0

Kod çalışmıyor, ben bir n00b. Dosyayı kilitleyen MD5hash'tan sonra dosyayı yeniden kullanıyordum. – mattdwen

+0

Kötü bir fikir nedir? Kodun neden çalışmadığını anlamasına yardım ettim. Büyük bir dosyanın kilitlenmesini engellemek, dünyanın sonu değildir. Tam olarak ne söylüyorsun, cevabımın onun kodunun gerçekten işe yaradığını ve bunu göstermek için bir örnek oluşturduğuna dair cevabım yanlış mı? @amin, daha fazla bağlam verebilir misiniz? –

1

MD5 nesnesini bir() yönteminde de mi sarmayı denediniz? Dokümanlardan MD5 Tek Kullanımlıktır. Bu dosyayı bırakabilir.

+0

Evet, muhtemelen bir dosya adı alan ve bir karma dizesi döndüren bir işlevi soyutlamak isteyebilirsiniz. – Mark

-1

Dosya silmeden önce null olarak md5Hasher ayarını denediniz mi? Muhtemelen FileStream'e bağlı bir tutamacı (belki de bellek sızıntısı) vardır.

+2

Bir değişkenin null olarak ayarlanması, hala bellekte olup olmadığına ve hala bazı kaynaklara tutulduğu üzerine hemen hiçbir etkisi yoktur. Çöp toplayıcısının ve son haline getiricisinin, bir değişkeni null olarak belirleyen kodun ayarlanması ile bundan sonra takip edilen kod satırlarının arasına girmesi pek olası değildir. Aslında, derleyici, değişkeni null olarak belirleyen satırı göz ardı edebilir. Bu kesinlikle bertaraf, çöp toplama veya sonuçlandırmayı tetiklemeyecektir. –

-1

Dosyayı neden FileShare.ReadWrite ile açmıyorsunuz? Döngüsünüzün yapılışından sonra

20

İthalat adı boşluk

using System.Security.Cryptography; 
İşte

size md5 hash kodu döndürür işlevdir. Dizeyi parametre olarak iletmeniz gerekir.

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