diff options
Diffstat (limited to 'Emby.Common.Implementations/IO/ManagedFileSystem.cs')
| -rw-r--r-- | Emby.Common.Implementations/IO/ManagedFileSystem.cs | 262 |
1 files changed, 236 insertions, 26 deletions
diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index 0c1c02cd5..ba73c1ba2 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -23,6 +23,8 @@ namespace Emby.Common.Implementations.IO private string _tempPath; + private SharpCifsFileSystem _sharpCifsFileSystem; + public ManagedFileSystem(ILogger logger, IEnvironmentInfo environmentInfo, string tempPath) { Logger = logger; @@ -34,6 +36,8 @@ namespace Emby.Common.Implementations.IO environmentInfo.OperatingSystem != MediaBrowser.Model.System.OperatingSystem.OSX; SetInvalidFileNameChars(environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows); + + _sharpCifsFileSystem = new SharpCifsFileSystem(environmentInfo.OperatingSystem); } public void AddShortcutHandler(IShortcutHandler handler) @@ -65,14 +69,6 @@ namespace Emby.Common.Implementations.IO } } - public char PathSeparator - { - get - { - return Path.PathSeparator; - } - } - public string GetFullPath(string path) { return Path.GetFullPath(path); @@ -168,6 +164,11 @@ namespace Emby.Common.Implementations.IO throw new ArgumentNullException("path"); } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileSystemInfo(path); + } + // Take a guess to try and avoid two file system hits, but we'll double-check by calling Exists if (Path.HasExtension(path)) { @@ -208,6 +209,11 @@ namespace Emby.Common.Implementations.IO throw new ArgumentNullException("path"); } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileInfo(path); + } + var fileInfo = new FileInfo(path); return GetFileSystemMetadata(fileInfo); @@ -228,6 +234,11 @@ namespace Emby.Common.Implementations.IO throw new ArgumentNullException("path"); } + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectoryInfo(path); + } + var fileInfo = new DirectoryInfo(path); return GetFileSystemMetadata(fileInfo); @@ -374,6 +385,11 @@ namespace Emby.Common.Implementations.IO /// <returns>FileStream.</returns> public Stream GetFileStream(string path, FileOpenMode mode, FileAccessMode access, FileShareMode share, bool isAsync = false) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileStream(path, mode, access, share); + } + if (_supportsAsyncFileStreams && isAsync) { return new FileStream(path, GetFileMode(mode), GetFileAccess(access), GetFileShare(share), 262144, true); @@ -386,8 +402,8 @@ namespace Emby.Common.Implementations.IO { switch (mode) { - case FileOpenMode.Append: - return FileMode.Append; + //case FileOpenMode.Append: + // return FileMode.Append; case FileOpenMode.Create: return FileMode.Create; case FileOpenMode.CreateNew: @@ -396,8 +412,8 @@ namespace Emby.Common.Implementations.IO return FileMode.Open; case FileOpenMode.OpenOrCreate: return FileMode.OpenOrCreate; - case FileOpenMode.Truncate: - return FileMode.Truncate; + //case FileOpenMode.Truncate: + // return FileMode.Truncate; default: throw new Exception("Unrecognized FileOpenMode"); } @@ -407,8 +423,8 @@ namespace Emby.Common.Implementations.IO { switch (mode) { - case FileAccessMode.ReadWrite: - return FileAccess.ReadWrite; + //case FileAccessMode.ReadWrite: + // return FileAccess.ReadWrite; case FileAccessMode.Write: return FileAccess.Write; case FileAccessMode.Read: @@ -437,6 +453,12 @@ namespace Emby.Common.Implementations.IO public void SetHidden(string path, bool isHidden) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.SetHidden(path, isHidden); + return; + } + var info = GetFileInfo(path); if (info.Exists && info.IsHidden != isHidden) @@ -456,6 +478,12 @@ namespace Emby.Common.Implementations.IO public void SetReadOnly(string path, bool isReadOnly) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.SetReadOnly(path, isReadOnly); + return; + } + var info = GetFileInfo(path); if (info.Exists && info.IsReadOnly != isReadOnly) @@ -508,6 +536,16 @@ namespace Emby.Common.Implementations.IO CopyFile(temp1, file2, true); } + private char GetDirectorySeparatorChar(string path) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectorySeparatorChar(path); + } + + return Path.DirectorySeparatorChar; + } + public bool AreEqual(string path1, string path2) { if (path1 == null && path2 == null) @@ -520,8 +558,8 @@ namespace Emby.Common.Implementations.IO return false; } - path1 = path1.TrimEnd(DirectorySeparatorChar); - path2 = path2.TrimEnd(DirectorySeparatorChar); + path1 = path1.TrimEnd(GetDirectorySeparatorChar(path1)); + path2 = path2.TrimEnd(GetDirectorySeparatorChar(path2)); return string.Equals(path1, path2, StringComparison.OrdinalIgnoreCase); } @@ -538,7 +576,9 @@ namespace Emby.Common.Implementations.IO throw new ArgumentNullException("path"); } - return path.IndexOf(parentPath.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) != -1; + var separatorChar = GetDirectorySeparatorChar(parentPath); + + return path.IndexOf(parentPath.TrimEnd(separatorChar) + separatorChar, StringComparison.OrdinalIgnoreCase) != -1; } public bool IsRootPath(string path) @@ -570,7 +610,7 @@ namespace Emby.Common.Implementations.IO return path; } - return path.TrimEnd(Path.DirectorySeparatorChar); + return path.TrimEnd(GetDirectorySeparatorChar(path)); } public string GetFileNameWithoutExtension(FileSystemMetadata info) @@ -609,6 +649,12 @@ namespace Emby.Common.Implementations.IO public void DeleteFile(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.DeleteFile(path); + return; + } + var fileInfo = GetFileInfo(path); if (fileInfo.Exists) @@ -628,11 +674,23 @@ namespace Emby.Common.Implementations.IO public void DeleteDirectory(string path, bool recursive) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.DeleteDirectory(path, recursive); + return; + } + Directory.Delete(path, recursive); } public void CreateDirectory(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.CreateDirectory(path); + return; + } + Directory.CreateDirectory(path); } @@ -655,128 +713,280 @@ namespace Emby.Common.Implementations.IO public IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectories(path, recursive); + } + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - return ToMetadata(path, new DirectoryInfo(path).EnumerateDirectories("*", searchOption)); + return ToMetadata(new DirectoryInfo(path).EnumerateDirectories("*", searchOption)); } public IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false) { + return GetFiles(path, null, false, recursive); + } + + public IEnumerable<FileSystemMetadata> GetFiles(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFiles(path, extensions, enableCaseSensitiveExtensions, recursive); + } + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - return ToMetadata(path, new DirectoryInfo(path).EnumerateFiles("*", searchOption)); + // On linux and osx the search pattern is case sensitive + // If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method + if (enableCaseSensitiveExtensions && extensions != null && extensions.Length == 1) + { + return ToMetadata(new DirectoryInfo(path).EnumerateFiles("*" + extensions[0], searchOption)); + } + + var files = new DirectoryInfo(path).EnumerateFiles("*", searchOption); + + if (extensions != null && extensions.Length > 0) + { + files = files.Where(i => + { + var ext = i.Extension; + if (ext == null) + { + return false; + } + return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }); + } + + return ToMetadata(files); } public IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileSystemEntries(path, recursive); + } + var directoryInfo = new DirectoryInfo(path); var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; if (EnableFileSystemRequestConcat) { - return ToMetadata(path, directoryInfo.EnumerateDirectories("*", searchOption)) - .Concat(ToMetadata(path, directoryInfo.EnumerateFiles("*", searchOption))); + return ToMetadata(directoryInfo.EnumerateDirectories("*", searchOption)) + .Concat(ToMetadata(directoryInfo.EnumerateFiles("*", searchOption))); } - return ToMetadata(path, directoryInfo.EnumerateFileSystemInfos("*", searchOption)); + return ToMetadata(directoryInfo.EnumerateFileSystemInfos("*", searchOption)); } - private IEnumerable<FileSystemMetadata> ToMetadata(string parentPath, IEnumerable<FileSystemInfo> infos) + private IEnumerable<FileSystemMetadata> ToMetadata(IEnumerable<FileSystemInfo> infos) { return infos.Select(GetFileSystemMetadata); } public string[] ReadAllLines(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllLines(path); + } return File.ReadAllLines(path); } public void WriteAllLines(string path, IEnumerable<string> lines) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllLines(path, lines); + return; + } File.WriteAllLines(path, lines); } public Stream OpenRead(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.OpenRead(path); + } return File.OpenRead(path); } public void CopyFile(string source, string target, bool overwrite) { + if (_sharpCifsFileSystem.IsEnabledForPath(source)) + { + _sharpCifsFileSystem.CopyFile(source, target, overwrite); + return; + } File.Copy(source, target, overwrite); } public void MoveFile(string source, string target) { + if (_sharpCifsFileSystem.IsEnabledForPath(source)) + { + _sharpCifsFileSystem.MoveFile(source, target); + return; + } File.Move(source, target); } public void MoveDirectory(string source, string target) { + if (_sharpCifsFileSystem.IsEnabledForPath(source)) + { + _sharpCifsFileSystem.MoveDirectory(source, target); + return; + } Directory.Move(source, target); } public bool DirectoryExists(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.DirectoryExists(path); + } return Directory.Exists(path); } public bool FileExists(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.FileExists(path); + } return File.Exists(path); } public string ReadAllText(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllText(path); + } return File.ReadAllText(path); } public byte[] ReadAllBytes(string path) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllBytes(path); + } return File.ReadAllBytes(path); } public void WriteAllText(string path, string text, Encoding encoding) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllText(path, text, encoding); + return; + } + File.WriteAllText(path, text, encoding); } public void WriteAllText(string path, string text) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllText(path, text); + return; + } + File.WriteAllText(path, text); } public void WriteAllBytes(string path, byte[] bytes) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + _sharpCifsFileSystem.WriteAllBytes(path, bytes); + return; + } + File.WriteAllBytes(path, bytes); } public string ReadAllText(string path, Encoding encoding) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.ReadAllText(path, encoding); + } + return File.ReadAllText(path, encoding); } public IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetDirectoryPaths(path, recursive); + } + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; return Directory.EnumerateDirectories(path, "*", searchOption); } public IEnumerable<string> GetFilePaths(string path, bool recursive = false) { + return GetFilePaths(path, null, false, recursive); + } + + public IEnumerable<string> GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false) + { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFilePaths(path, extensions, enableCaseSensitiveExtensions, recursive); + } + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; - return Directory.EnumerateFiles(path, "*", searchOption); + + // On linux and osx the search pattern is case sensitive + // If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method + if (enableCaseSensitiveExtensions && extensions != null && extensions.Length == 1) + { + return Directory.EnumerateFiles(path, "*" + extensions[0], searchOption); + } + + var files = Directory.EnumerateFiles(path, "*", searchOption); + + if (extensions != null && extensions.Length > 0) + { + files = files.Where(i => + { + var ext = Path.GetExtension(i); + if (ext == null) + { + return false; + } + return extensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }); + } + + return files; } public IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false) { + if (_sharpCifsFileSystem.IsEnabledForPath(path)) + { + return _sharpCifsFileSystem.GetFileSystemEntryPaths(path, recursive); + } + var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; return Directory.EnumerateFileSystemEntries(path, "*", searchOption); } public virtual void SetExecutable(string path) { - + } } } |
