2012-12-28 1 views
1

디렉토리와 그 안에있는 모든 파일의 크기를 계산하는 간단한 방법이 있습니다.디렉토리의 크기를 계산하는 동안 UnauthorizedAccessException 받기

using System; 
using System.IO; 

namespace MyProject.Libs 
{ 
    public sealed class DirectorySize 
    { 
     public static long GetDirectorySize(DirectoryInfo dir) 
     { 
      long total = 0; 

      FileInfo[] fileInfos = dir.GetFiles(); 
      foreach (FileInfo fileInfo in fileInfos) 
      { 
       total += fileInfo.Length; 
      } 

      DirectoryInfo[] dirInfos = dir.GetDirectories(); 
      foreach (DirectoryInfo dirInfo in dirInfos) 
      { 
       total += DirectorySize.GetDirectorySize(dirInfo); 
      } 

      return total; 
     } 
    } 
} 

I C 드라이브에 사용 : 다음 코드는 내가 메시지와 함께 "UnauthorizedAccessException"를 얻을 \ "경로에 대한 액세스가 'C : \ 문서 및 설정'. 거부" 즉 :

DirectoryInfo di = new DirectoryInfo(Path.GetPathRoot(Environment.SystemDirectory)); 
long ds = DirectorySize.GetDirectorySize(di); 

Visual Studio를 관리자로 실행하려고 시도했습니다. 모두 같은. 왜?

+0

Vista 이후 C : \ Documents and Settings 폴더를 볼 수 없습니다. 대신 C : \ Users를 사용해보십시오. –

+0

어디에서 예외가 발생합니까? try catch 문에서 DirectioryInfo를 감싸려고 했습니까? – eandersson

+0

'FileInfo [] fileInfos = dir.GetFiles();'에서 예외가 발생합니다. 또한, 나는'Environment.SystemDirectory'를 시작점으로 사용하므로 어떤 디렉토리가 발견되는지에 대해서는 아무런 통제권이 없습니다.try/catch 블록을 사용하려고했지만 잘못된 총 크기를 얻습니다. –

답변

2

코드가 C:\Documents and Settings 인 경우 오류가 발생하고 C:\Users을 가리키는 junction point이됩니다. 디렉토리의 FileAttributes.ReparsePoint으로 확인할 수 있습니다. 여기

는 (당신은 권한이없는 다른 DIRS에 대한) 추가 예외 처리와 수정 된 코드입니다 :

public sealed class DirectorySize 
{ 
    public static long GetDirectorySize(DirectoryInfo dir) 
    { 
     long total = 0; 
     FileAttributes attributes = File.GetAttributes(dir.FullName); 
     if (!((attributes & FileAttributes.ReparsePoint) == FileAttributes.ReparsePoint)) 
     { 
      try{ 
       FileInfo[] fileInfos = dir.GetFiles(); 
       foreach (FileInfo fileInfo in fileInfos) 
       { 
        total += fileInfo.Length; 
       } 

       DirectoryInfo[] dirInfos = dir.GetDirectories(); 
       foreach (DirectoryInfo dirInfo in dirInfos) 
       { 
        total += DirectorySize.GetDirectorySize(dirInfo); 
       } 
      } catch (UnauthorizedAccessException) 
      { 
       // log this? 
      } 
     } 

     return total; 
    } 
} 

Junction Points (Windows) Windows Vista 및 Windows Server 2008에서

, 의 기본 위치 사용자 데이터 및 시스템 데이터가 변경되었습니다. 예를 들어, 이 % SystemDrive % \ Documents 및 Settings 디렉터리에 저장되어있는 사용자 데이터는 이제 % SystemDrive % \ Users 디렉터리에 저장됩니다. 이전 버전과의 호환성을 위해 이전 위치에는 이 새 위치를 가리키는 연결점이 있습니다. 예를 들어, C : \ Documents 및 설정C : \ Users을 가리키는 연결 지점 인 입니다. 백업 응용 프로그램은 이 연결 지점을 백업하고 복원 할 수 있어야합니다. 그들은 FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_HIDDEN 있고, FILE_ATTRIBUTE_SYSTEM 파일 속성이 설정되어 다음과 같이이 연결 포인트를 식별 할 수 있습니다. 또한 액세스 제어 목록 (ACL) 에 액세스 을 설정하면 모두에게 읽기 액세스가 거부됩니다 (). 특정 경로를 호출하는 응용 프로그램은 에 필요한 권한이있는 경우 이러한 연결 지점을 통과 할 수 있습니다. 그러나 은 연결 지점의 내용을 열거하면 오류가 발생합니다 ().

+0

환상적입니다. 이로 인해 문제가 해결되었습니다. 감사! –

0

관리자에게도 방문 권한이없는 폴더가 있습니다. 대부분의 시간은 번역 된 시스템에서 발생합니다. 예를 들어, "program files"폴더는 "program"이라고합니다. 코드 내에서 "프로그램"에 액세스 할 수는 없지만 "프로그램 파일"

+0

사람들이 응용 프로그램에 경로를 하드 코딩하지 못하도록하는 좋은 정보이지만,이 경우 OP는 C 드라이브의 모든 디렉토리를 열거하고 예외를 던지는 이유가 궁금합니다. 이 때문에 번역 오류 일 수 없으므로 또 다른 근본 원인 (evanmcdonnal로 식별 됨)이 있습니다. –

3

관리자 권한을 갖고 있지 않은 파일 및 폴더에는 액세스 권한이 없습니다. 가능한 한 최선을 다하면 예외 처리를 추가하고 반환하는 정보가 합리적으로 완성되기를 바랍니다.

관련 문제