2009-05-06 6 views
12

편집 : 코드 예기치 않은대로 예제를 retitled했습니다.C# MD5 hasher 예

파일을 복사하고 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 문을 사용하면 filestream이 제대로 종료 될 것으로 예상됩니다. 나는 또한 using을 제거하고 읽은 후에 fs.Close()fs.Dispose()을 넣고 별도로 파일 스트림을 선언하려고 시도했다.

이 후, 나는 실제로 md5 계산을 주석 처리하고, 코드는 삭제되고 파일과 함께 실행되므로 ComputeHash(fs)과 관련이있는 것처럼 보입니다.

+1

왜 그냥 ReadAllBytes()를 호출하고 끝내지 않으시겠습니까? – BobbyShaftoe

+1

computeHash에 대한 그의 호출은 스트림에서 작동하기 때문에 파일이 크면 메모리에 전체를 저장할 필요가 없습니다. –

+0

파일을 삭제하기 전에 파일을 닫지 않아도됩니까? – JonnyBoats

답변

15

코드를 콘솔 앱에 넣고 오류없이 실행 한 결과, 해시가 생겼고 테스트 파일이 실행 종료시 삭제 되었습니까? 방금 테스트 응용 프로그램의 .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; 
     } 
    } 
} 
+0

코드가 작동하지만, 나는 n00b입니다. 파일을 잠그고있는 MD5hash 뒤에 파일을 재사용하고있었습니다. – mattdwen

+0

나쁜 생각은 무엇입니까? 나는 코드가 왜 작동하지 않는지 알아내는 것을 도왔다. 큰 파일을 복사하여 잠글 수 없게하는 것이 세계의 끝이 아닙니다. 당신이 말하는 것은 정확하게 그의 코드가 실제로 작동한다는 것과 그 설명을위한 샘플을 만드는 것에 대한 그의 대답에 잘못된 것인가? @amin, 문맥을 좀 더 알려주시겠습니까? –

1

MD5 객체를 using()에서도 래핑 했습니까? 문서에서 MD5는 일회용입니다. 그러면 파일을 놓을 수 있습니다.

+0

네, 아마도 파일명을 취하고 해시 문자열을 반환하는 함수를 추상화하고 싶을 것입니다. – Mark

-1

파일을 삭제하기 전에 md5Hasher를 null로 설정해 보셨습니까? 아마도 FileStream (메모리 누수)에 여전히 연결된 핸들이있을 것입니다.

+2

변수를 null로 설정해도 여전히 메모리에 있는지 여부와 일부 리소스를 계속 보유하고 있는지 여부에 직접적인 영향을주지 않습니다. 가비지 컬렉터와 그 파이널 라이저는 변수를 널 (null)로 설정하는 코드와 그로부터 오는 코드의 라인 사이에 끼어 들지는 않을 것입니다. 실제로 컴파일러는 변수를 null로 설정하는 행을 무시할 수 있습니다. 확실히 처리, 가비지 수집 또는 종료를 트리거하지 않습니다. –

-1

왜 FileShare.ReadWrite로 파일을 열지 않습니까?

20

가져 오기 이름 공간

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