2009-05-06 34 views
12

Chỉnh sửa: Tôi đã đổi tên này thành ví dụ khi mã hoạt động như mong đợi.C# MD5 hasher example

Tôi đang cố gắng sao chép tệp, nhận băm MD5, sau đó xóa bản sao. Tôi đang làm điều này để tránh khóa quy trình trên tệp gốc, mà một ứng dụng khác ghi vào đó. Tuy nhiên, tôi đang nhận được một khóa trên tập tin tôi đã sao chép.

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

Tôi sau đó nhận được 'quy trình không thể truy cập tệp' ngoại lệ trên File.Delete() '.

Tôi hy vọng rằng với tuyên bố using, luồng phim sẽ bị đóng độc đáo. Tôi cũng đã cố gắng khai báo riêng dòng phim, xóa using và đặt fs.Close()fs.Dispose() sau khi đọc.

Sau này, tôi nhận xét tính toán md5 thực sự, và đoạn mã excutes, với tập tin bị xóa, do đó, nó trông giống như nó là một cái gì đó để làm với ComputeHash(fs).

+1

Tại sao bạn không chỉ gọi ReadAllBytes() và được thực hiện với nó? – BobbyShaftoe

+1

Bởi vì cuộc gọi của anh ta để computeHash hoạt động trên luồng - nếu tệp lớn, anh ta sẽ không cần phải giữ tất cả trong bộ nhớ. –

+0

Bạn không cần đóng tệp trước khi xóa nó? – JonnyBoats

Trả lời

15

Tôi lấy mã của bạn đặt nó trong một ứng dụng giao diện điều khiển và chạy nó không có lỗi, có băm và các tập tin thử nghiệm sẽ bị xóa vào cuối thực hiện? Tôi chỉ sử dụng .pdb từ ứng dụng thử nghiệm của tôi như là tập tin.

Bạn đang chạy phiên bản .NET nào?

Tôi đang đặt mã mà tôi có mà làm việc ở đây, và nếu bạn đặt điều này trong một ứng dụng giao diện điều khiển trong VS2008 .NET 3.5 sp1 nó chạy không có lỗi (ít nhất là cho tôi).

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

Mã không hoạt động, tôi là một n00b. Tôi đã sử dụng lại tệp sau khi MD5hash đã khóa tệp. – mattdwen

+0

Ý tưởng tồi là gì? Tôi đã giúp anh ta tìm ra lý do tại sao mã không hoạt động. Sao chép một tập tin lớn để giữ nó khỏi bị khóa không phải là kết thúc của thế giới. Chính xác những gì bạn đang nói là sai với câu trả lời của tôi cho anh ta rằng mã của mình thực sự hoạt động và tạo ra một mẫu để minh họa cho nó? @amin, Bạn có thể vui lòng cung cấp thêm ngữ cảnh? –

1

Bạn đã thử gói đối tượng MD5 của bạn trong một using() quá? Từ các tài liệu, MD5 là Dùng một lần. Điều đó có thể làm cho nó đi ra khỏi tập tin.

+0

Vâng, bạn có thể muốn trừu tượng một hàm lấy tên tệp và trả về một chuỗi băm. – Mark

-1

Bạn đã thử đặt md5Hasher thành null trước khi xóa tệp chưa? Nó có lẽ có một xử lý vẫn còn gắn liền với FileStream (bộ nhớ rò rỉ có lẽ).

+2

Đặt một biến thành null không có hiệu lực ngay lập tức cho dù nó vẫn còn trong bộ nhớ và vẫn giữ một số tài nguyên. Bộ thu gom rác và trình hoàn thiện của nó rất khó có thể khởi động giữa việc thiết lập mã để đặt một biến thành null và các dòng mã theo sau từ đó. Trong thực tế, trình biên dịch cũng có thể bỏ qua dòng thiết lập biến thành null. Nó chắc chắn sẽ không kích hoạt hoặc xử lý, thu gom rác thải hoặc hoàn thiện. –

-1

Tại sao không mở tệp bằng FileShare.ReadWrite?

0

md5hasher.Clear() sau khi vòng lặp của bạn có thể thực hiện thủ thuật.

20

nhập tên không gian

using System.Security.Cryptography; 

Đây là hàm trả về bạn mã băm md5. Bạn cần phải vượt qua chuỗi như tham số.

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