첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

▶ WIN32 API를 사용해 디렉토리 크기 구하기 예제

using System;

int fileCount      = 0;
int directoryCount = 0;

long directorySize = DirectorySizeHelper.GetDirectorySize("d:\\ARCA", -1, out fileCount, out directoryCount);

Console.WriteLine(directorySize);

 

728x90

 

▶ WIN32 API를 사용해 디렉토리 크기 구하기

using System;
using System.Runtime.InteropServices;

/// <summary>
/// 디렉토리 크기 헬퍼
/// </summary>
public static class DirectorySizeHelper
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Struct
    ////////////////////////////////////////////////////////////////////////////////////////// Private

    #region 파일 시간 - FILE_TIME

    /// <summary>
    /// 파일 시간
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    private struct FILE_TIME
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 날짜/시간 (하위)
        /// </summary>
        public uint DateTimeLow;

        /// <summary>
        /// 날짜/시간 (상위)
        /// </summary>
        public uint DateTimeHigh;

        #endregion
    }

    #endregion
    #region 데이터 찾기 - FIND_DATA

    /// <summary>
    /// 데이터 찾기
    /// </summary>
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct FIND_DATA
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 파일 어트리뷰트
        /// </summary>
        public uint FileAttributes;

        /// <summary>
        /// 생성 시간
        /// </summary>
        public FILE_TIME CreationTime;

        /// <summary>
        /// 최근 액세스 시간
        /// </summary>
        public FILE_TIME LastAccessTime;

        /// <summary>
        /// 최근 작성 시간
        /// </summary>
        public FILE_TIME LastWriteTime;

        /// <summary>
        /// 파일 크기 (상위)
        /// </summary>
        public uint FileSizeHigh;

        /// <summary>
        /// 파일 크기 (하위)
        /// </summary>
        public uint FileSizeLow;

        /// <summary>
        /// 예약어 0
        /// </summary>
        public uint Reserved0;

        /// <summary>
        /// 예약어 1
        /// </summary>
        public uint Reserved1;

        /// <summary>
        /// 파일명
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string FileName;

        /// <summary>
        /// 대체 파일명
        /// </summary>
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string AlternateFileName;

        #endregion
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Import
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Private

    #region 첫번째 파일 찾기 - FindFirstFile(fileName, findData)

    /// <summary>
    /// 첫번째 파일 찾기
    /// </summary>
    /// <param name="fileName">파일명</param>
    /// <param name="findData">찾기 데이터</param>
    /// <returns>파일 핸들</returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    private static extern IntPtr FindFirstFile(string fileName, out FIND_DATA findData);

    #endregion
    #region 다음 파일 찾기 - FindNextFile(fileHandle, findData)

    /// <summary>
    /// 다음 파일 찾기
    /// </summary>
    /// <param name="fileHandle">파일 핸들</param>
    /// <param name="findData">찾기 데이터</param>
    /// <returns>처리 결과</returns>
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    private static extern bool FindNextFile(IntPtr fileHandle, out FIND_DATA findData);

    #endregion
    #region 찾기 닫기 - FindClose(fileHandle)

    /// <summary>
    /// 찾기 닫기
    /// </summary>
    /// <param name="fileHandle">파일 핸들</param>
    /// <returns>처리 결과</returns>
    [DllImport("kernel32.dll")]
    private static extern bool FindClose(IntPtr fileHandle);

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Field
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Private

    #region Field

    /// <summary>
    /// 파일 어트리뷰트 디렉토리
    /// </summary>
    private static readonly int FILE_ATTRIBUTE_DIRECTORY = 0x10;

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Public

    #region 디렉토리 크기 구하기 - GetDirectorySize(sourceDirectoryPath, directoryLevel, fileCount, directoryCount)

    /// <summary>
    /// 디렉토리 크기 구하기
    /// </summary>
    /// <param name="sourceDirectoryPath">소스 디렉토리 경로</param>
    /// <param name="directoryLevel">디렉토리 레벨</param>
    /// <param name="fileCount">파일 카운트</param>
    /// <param name="directoryCount">디렉토리 카운트</param>
    /// <returns>디렉토리 크기</returns>
    public static long GetDirectorySize(string sourceDirectoryPath, int directoryLevel, out int fileCount, out int directoryCount)
    {
        IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

        long directorySize = 0L;

        fileCount      = 0;
        directoryCount = 0;

        FIND_DATA findData;

        IntPtr fileHandle;

        fileHandle = FindFirstFile(@"\\?\" + sourceDirectoryPath + @"\*", out findData);

        if(fileHandle != INVALID_HANDLE_VALUE)
        {
            do
            {
                if((findData.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
                {
                    if(findData.FileName != "." && findData.FileName != "..")
                    {
                        directoryCount++;

                        int childFileCount;
                        int childDirectoryCount;

                        string childDirectoryPath = sourceDirectoryPath + (sourceDirectoryPath.EndsWith(@"\") ? "" : @"\") + findData.FileName;

                        if(directoryLevel != 0)
                        {
                            directorySize += GetDirectorySize(childDirectoryPath, directoryLevel - 1, out childFileCount, out childDirectoryCount);

                            directoryCount += childDirectoryCount;

                            fileCount += childFileCount;
                        }
                    }
                }
                else
                {
                    fileCount++;

                    directorySize += (long)findData.FileSizeLow + (long)findData.FileSizeHigh * 4294967296;
                }
            }
            while(FindNextFile(fileHandle, out findData));

            FindClose(fileHandle);
        }

        return directorySize;
    }

    #endregion
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요