예제 #1
0
        public static IEnumerable <DirectoryEntry> EnumDirectoryEntries(string path, string searchPattern, bool recursive, Func <uint, bool> attributeFilter)
        {
#if !WINDOWS
            throw new NotImplementedException();
#else
            if (!System.IO.Directory.Exists(path))
            {
                throw new System.IO.DirectoryNotFoundException();
            }

            var    buffer      = new StringBuilder();
            string actualPath  = System.IO.Path.GetFullPath(path + @"\");
            var    patterns    = searchPattern.Split(';');
            var    globs       = (from p in patterns select GlobToRegex(p)).ToArray();
            var    findData    = new WIN32_FIND_DATA();
            var    searchPaths = new Queue <string>();
            var    entry       = new DirectoryEntry();
            searchPaths.Enqueue("");

            while (searchPaths.Count != 0)
            {
                string currentPath = searchPaths.Dequeue();

                buffer.Remove(0, buffer.Length);
                buffer.Append(actualPath);
                buffer.Append(currentPath);
                buffer.Append("*");

                using (var handle = new FindHandle(FindFirstFile(buffer.ToString(), out findData)))
                    while (handle.Valid)
                    {
                        string fileName = findData.cFileName;

                        if ((fileName != ".") && (fileName != ".."))
                        {
                            bool isDirectory = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
                            bool masked      = !attributeFilter(findData.dwFileAttributes);

                            buffer.Remove(0, buffer.Length);
                            buffer.Append(actualPath);
                            buffer.Append(currentPath);
                            buffer.Append(fileName);

                            if (isDirectory)
                            {
                                buffer.Append("\\");
                            }

                            if (recursive && isDirectory)
                            {
                                var subdir = buffer.ToString().Substring(actualPath.Length);
                                searchPaths.Enqueue(subdir);
                            }

                            if (!masked)
                            {
                                string fileNameLower = fileName.ToLower();

                                bool globMatch = false;
                                foreach (var glob in globs)
                                {
                                    if (glob.IsMatch(fileNameLower))
                                    {
                                        globMatch = true;
                                        break;
                                    }
                                }

                                if (globMatch)
                                {
                                    entry.Name         = buffer.ToString();
                                    entry.Attributes   = findData.dwFileAttributes;
                                    entry.Size         = findData.dwFileSizeLow + (findData.dwFileSizeHigh * ((ulong)(UInt32.MaxValue) + 1));
                                    entry.Created      = findData.ftCreationTime;
                                    entry.LastAccessed = findData.ftLastAccessTime;
                                    entry.LastWritten  = findData.ftLastWriteTime;
                                    entry.IsDirectory  = isDirectory;
                                    yield return(entry);
                                }
                            }
                        }

                        if (!FindNextFile(handle, out findData))
                        {
                            break;
                        }
                    }
            }
#endif
        }
예제 #2
0
파일: IO.cs 프로젝트: sq/Fracture
        public static IEnumerable<DirectoryEntry> EnumDirectoryEntries(string path, string searchPattern, bool recursive, Func<uint, bool> attributeFilter)
        {
            #if !WINDOWS
            throw new NotImplementedException();
            #else
            if (!System.IO.Directory.Exists(path))
                throw new System.IO.DirectoryNotFoundException();

            var buffer = new StringBuilder();
            string actualPath = System.IO.Path.GetFullPath(path + @"\");
            var patterns = searchPattern.Split(';');
            var globs = (from p in patterns select GlobToRegex(p)).ToArray();
            var findData = new WIN32_FIND_DATA();
            var searchPaths = new Queue<string>();
            var entry = new DirectoryEntry();
            searchPaths.Enqueue("");

            while (searchPaths.Count != 0) {
                string currentPath = searchPaths.Dequeue();

                buffer.Remove(0, buffer.Length);
                buffer.Append(actualPath);
                buffer.Append(currentPath);
                buffer.Append("*");

                using (var handle = new FindHandle(FindFirstFile(buffer.ToString(), out findData)))
                while (handle.Valid) {
                    string fileName = findData.cFileName;

                    if ((fileName != ".") && (fileName != "..")) {
                        bool isDirectory = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
                        bool masked = !attributeFilter(findData.dwFileAttributes);

                        buffer.Remove(0, buffer.Length);
                        buffer.Append(actualPath);
                        buffer.Append(currentPath);
                        buffer.Append(fileName);

                        if (isDirectory)
                            buffer.Append("\\");

                        if (recursive && isDirectory) {
                            var subdir = buffer.ToString().Substring(actualPath.Length);
                            searchPaths.Enqueue(subdir);
                        }

                        if (!masked) {
                            string fileNameLower = fileName.ToLower();

                            bool globMatch = false;
                            foreach (var glob in globs) {
                                if (glob.IsMatch(fileNameLower)) {
                                    globMatch = true;
                                    break;
                                }
                            }

                            if (globMatch) {
                                entry.Name = buffer.ToString();
                                entry.Attributes = findData.dwFileAttributes;
                                entry.Size = findData.dwFileSizeLow + (findData.dwFileSizeHigh * ((ulong)(UInt32.MaxValue) + 1));
                                entry.Created = findData.ftCreationTime;
                                entry.LastAccessed = findData.ftLastAccessTime;
                                entry.LastWritten = findData.ftLastWriteTime;
                                entry.IsDirectory = isDirectory;
                                yield return entry;
                            }
                        }
                    }

                    if (!FindNextFile(handle, out findData))
                        break;
                }
            }
            #endif
        }