using MediaBrowser.Model.Logging; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using CommonIO; namespace MediaBrowser.Controller.Providers { public class DirectoryService : IDirectoryService { private readonly ILogger _logger; private readonly IFileSystem _fileSystem; private readonly ConcurrentDictionary> _cache = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); public DirectoryService(ILogger logger, IFileSystem fileSystem) { _logger = logger; _fileSystem = fileSystem; } public DirectoryService(IFileSystem fileSystem) : this(new NullLogger(), fileSystem) { } public IEnumerable GetFileSystemEntries(string path) { return GetFileSystemEntries(path, false); } public Dictionary GetFileSystemDictionary(string path) { return GetFileSystemDictionary(path, false); } private Dictionary GetFileSystemDictionary(string path, bool clearCache) { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } Dictionary entries; if (clearCache) { Dictionary removed; _cache.TryRemove(path, out removed); } if (!_cache.TryGetValue(path, out entries)) { //_logger.Debug("Getting files for " + path); entries = new Dictionary(StringComparer.OrdinalIgnoreCase); try { // using EnumerateFileSystemInfos doesn't handle reparse points (symlinks) var list = _fileSystem.GetFileSystemEntries(path) .ToList(); // Seeing dupes on some users file system for some reason foreach (var item in list) { entries[item.FullName] = item; } } catch (DirectoryNotFoundException) { } //var group = entries.ToLookup(i => Path.GetDirectoryName(i.FullName)).ToList(); _cache.TryAdd(path, entries); } return entries; } private IEnumerable GetFileSystemEntries(string path, bool clearCache) { return GetFileSystemDictionary(path, clearCache).Values; } public IEnumerable GetFiles(string path) { return GetFiles(path, false); } public IEnumerable GetFiles(string path, bool clearCache) { return GetFileSystemEntries(path, clearCache).Where(i => !i.IsDirectory); } public FileSystemMetadata GetFile(string path) { return _fileSystem.GetFileInfo(path); //var directory = Path.GetDirectoryName(path); //if (string.IsNullOrWhiteSpace(directory)) //{ // _logger.Debug("Parent path is null for {0}", path); // return null; //} //try //{ // var dict = GetFileSystemDictionary(directory, false); // FileSystemMetadata entry; // dict.TryGetValue(path, out entry); // return entry; //} //catch (Exception ex) //{ // _logger.ErrorException("Error in GetFileSystemDictionary. Directory: :{0}. Original path: {1}", ex, directory, path); // return null; //} } public IEnumerable GetDirectories(string path) { return GetFileSystemEntries(path, false).Where(i => i.IsDirectory); } } }