aboutsummaryrefslogtreecommitdiff
path: root/Emby.Common.Implementations/IO/ManagedFileSystem.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Common.Implementations/IO/ManagedFileSystem.cs')
-rw-r--r--Emby.Common.Implementations/IO/ManagedFileSystem.cs262
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)
{
-
+
}
}
}