How to quickly check if folder is empty (.NET)?

后端 未结 18 831
旧时难觅i
旧时难觅i 2020-12-02 08:22

I have to check, if directory on disk is empty. It means, that it does not contain any folders/files. I know, that there is a simple method. We get array of FileSystemInfo\'

相关标签:
18条回答
  • 2020-12-02 08:37

    Here is the extra fast solution, that I finally implemented. Here I am using WinAPI and functions FindFirstFile, FindNextFile. It allows to avoid enumeration of all items in Folder and stops right after detecting the first object in the Folder. This approach is ~6(!!) times faster, than described above. 250 calls in 36ms!

    private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct WIN32_FIND_DATA
    {
        public uint dwFileAttributes;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
        public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
        public uint nFileSizeHigh;
        public uint nFileSizeLow;
        public uint dwReserved0;
        public uint dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string cFileName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
        public string cAlternateFileName;
    }
    
    [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
    private static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
    
    [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
    private static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);
    
    [DllImport("kernel32.dll")]
    private static extern bool FindClose(IntPtr hFindFile);
    
    public static bool CheckDirectoryEmpty_Fast(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            throw new ArgumentNullException(path);
        }
    
        if (Directory.Exists(path))
        {
            if (path.EndsWith(Path.DirectorySeparatorChar.ToString()))
                path += "*";
            else
                path += Path.DirectorySeparatorChar + "*";
    
            WIN32_FIND_DATA findData;
            var findHandle = FindFirstFile(path, out findData);
    
            if (findHandle != INVALID_HANDLE_VALUE)
            {
                try
                {
                    bool empty = true;
                    do
                    {
                        if (findData.cFileName != "." && findData.cFileName != "..")
                            empty = false;
                    } while (empty && FindNextFile(findHandle, out findData));
    
                    return empty;
                }
                finally
                {
                    FindClose(findHandle);
                }
            }
    
            throw new Exception("Failed to get directory first file",
                Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));
        }
        throw new DirectoryNotFoundException();
    }
    

    I hope it will be useful for somebody in the future.

    0 讨论(0)
  • 2020-12-02 08:37

    You will have to go the hard drive for this information in any case, and this alone will trump any object creation and array filling.

    0 讨论(0)
  • 2020-12-02 08:38

    Easy and simple:

    int num = Directory.GetFiles(pathName).Length;
    
    if (num == 0)
    {
       //empty
    }
    
    0 讨论(0)
  • 2020-12-02 08:44

    Use this. It's simple.

    Public Function IsDirectoryEmpty(ByVal strDirectoryPath As String) As Boolean
            Dim s() As String = _
                Directory.GetFiles(strDirectoryPath)
            If s.Length = 0 Then
                Return True
            Else
                Return False
            End If
        End Function
    
    0 讨论(0)
  • 2020-12-02 08:46

    I'm not aware of a method that will succinctly tell you if a given folder contains any other folders or files, however, using:

    Directory.GetFiles(path);
    &
    Directory.GetDirectories(path);
    

    should help performance since both of these methods will only return an array of strings with the names of the files/directories rather than entire FileSystemInfo objects.

    0 讨论(0)
  • 2020-12-02 08:47

    I don't know about the performance statistics on this one, but have you tried using the Directory.GetFiles() static method ?

    It returns a string array containing filenames (not FileInfos) and you can check the length of the array in the same way as above.

    0 讨论(0)
提交回复
热议问题