2017-08-21 19:48:45 +00:00
using System ;
2014-12-16 07:28:55 +00:00
using System.Collections.Generic ;
2011-10-23 05:26:43 +00:00
using System.IO ;
using System.Linq ;
2013-07-05 06:30:45 +00:00
using System.Security.AccessControl ;
2013-08-13 00:22:35 +00:00
using System.Security.Principal ;
2011-10-23 05:26:43 +00:00
using NLog ;
2013-05-24 22:18:37 +00:00
using NzbDrone.Common.EnsureThat ;
2014-07-31 19:33:56 +00:00
using NzbDrone.Common.EnvironmentInfo ;
2014-12-02 06:26:25 +00:00
using NzbDrone.Common.Extensions ;
2013-08-31 01:42:30 +00:00
using NzbDrone.Common.Instrumentation ;
2011-10-23 05:26:43 +00:00
2014-01-06 06:20:08 +00:00
namespace NzbDrone.Common.Disk
2011-10-23 05:26:43 +00:00
{
2014-01-06 06:20:08 +00:00
public abstract class DiskProviderBase : IDiskProvider
2011-10-23 05:26:43 +00:00
{
2014-12-17 07:12:26 +00:00
private static readonly Logger Logger = NzbDroneLogger . GetLogger ( typeof ( DiskProviderBase ) ) ;
2011-10-23 05:26:43 +00:00
2018-04-21 04:59:31 +00:00
public static StringComparison PathStringComparison
{
get
{
if ( OsInfo . IsWindows )
{
return StringComparison . OrdinalIgnoreCase ;
}
return StringComparison . Ordinal ;
}
}
2014-01-06 06:20:08 +00:00
public abstract long? GetAvailableSpace ( string path ) ;
public abstract void InheritFolderPermissions ( string filename ) ;
2014-01-31 05:24:32 +00:00
public abstract void SetPermissions ( string path , string mask , string user , string group ) ;
2014-01-06 06:20:08 +00:00
public abstract long? GetTotalSize ( string path ) ;
2014-10-14 21:31:35 +00:00
public DateTime FolderGetCreationTime ( string path )
2014-01-22 05:22:09 +00:00
{
2014-04-19 15:09:22 +00:00
CheckFolderExists ( path ) ;
2014-01-22 05:22:09 +00:00
2014-04-19 15:09:22 +00:00
return new DirectoryInfo ( path ) . CreationTimeUtc ;
2014-01-22 05:22:09 +00:00
}
2014-10-14 21:31:35 +00:00
public DateTime FolderGetLastWrite ( string path )
2012-01-23 04:34:30 +00:00
{
2014-04-19 15:09:22 +00:00
CheckFolderExists ( path ) ;
2012-01-23 04:34:30 +00:00
2012-01-23 04:59:23 +00:00
var dirFiles = GetFiles ( path , SearchOption . AllDirectories ) . ToList ( ) ;
if ( ! dirFiles . Any ( ) )
{
return new DirectoryInfo ( path ) . LastWriteTimeUtc ;
}
2014-10-14 21:31:35 +00:00
return dirFiles . Select ( f = > new FileInfo ( f ) ) . Max ( c = > c . LastWriteTimeUtc ) ;
2014-04-19 15:09:22 +00:00
}
2014-03-13 05:27:36 +00:00
public DateTime FileGetLastWrite ( string path )
2014-03-08 19:01:51 +00:00
{
2014-04-19 15:09:22 +00:00
CheckFileExists ( path ) ;
2014-03-08 19:01:51 +00:00
return new FileInfo ( path ) . LastWriteTimeUtc ;
}
2014-04-19 15:09:22 +00:00
private void CheckFolderExists ( string path )
{
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
if ( ! FolderExists ( path ) )
{
throw new DirectoryNotFoundException ( "Directory doesn't exist. " + path ) ;
}
}
private void CheckFileExists ( string path )
2012-08-29 15:34:51 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2012-08-29 15:34:51 +00:00
if ( ! FileExists ( path ) )
2013-09-13 04:59:29 +00:00
{
2012-08-29 15:34:51 +00:00
throw new FileNotFoundException ( "File doesn't exist: " + path ) ;
2013-09-13 04:59:29 +00:00
}
2012-08-29 15:34:51 +00:00
}
2013-08-03 03:01:16 +00:00
public void EnsureFolder ( string path )
2013-04-15 01:41:39 +00:00
{
if ( ! FolderExists ( path ) )
{
CreateFolder ( path ) ;
}
}
2013-08-03 03:01:16 +00:00
public bool FolderExists ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2011-10-23 05:26:43 +00:00
return Directory . Exists ( path ) ;
}
2013-07-26 05:55:19 +00:00
2013-08-03 03:01:16 +00:00
public bool FileExists ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2018-04-21 04:59:31 +00:00
return FileExists ( path , PathStringComparison ) ;
2011-10-23 05:26:43 +00:00
}
2014-12-07 20:54:07 +00:00
public bool FileExists ( string path , StringComparison stringComparison )
2013-07-24 06:26:10 +00:00
{
2014-07-31 19:33:56 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2014-12-07 20:54:07 +00:00
switch ( stringComparison )
2013-07-24 06:26:10 +00:00
{
2019-06-14 03:54:25 +00:00
case StringComparison . CurrentCulture :
case StringComparison . InvariantCulture :
case StringComparison . Ordinal :
{
return File . Exists ( path ) & & path = = path . GetActualCasing ( ) ;
}
2014-12-07 20:54:07 +00:00
default :
{
return File . Exists ( path ) ;
}
2013-07-24 06:26:10 +00:00
}
}
2017-08-21 19:48:45 +00:00
2015-01-21 19:59:03 +00:00
public bool FolderWritable ( string path )
{
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
try
{
2017-08-21 19:48:45 +00:00
var testPath = Path . Combine ( path , "radarr_write_test.txt" ) ;
2015-01-21 19:59:03 +00:00
var testContent = string . Format ( "This file was created to verify if '{0}' is writable. It should've been automatically deleted. Feel free to delete it." , path ) ;
File . WriteAllText ( testPath , testContent ) ;
File . Delete ( testPath ) ;
return true ;
}
catch ( Exception e )
{
Logger . Trace ( "Directory '{0}' isn't writable. {1}" , path , e . Message ) ;
return false ;
}
}
2013-08-03 03:01:16 +00:00
public string [ ] GetDirectories ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2012-01-23 06:43:11 +00:00
return Directory . GetDirectories ( path ) ;
2011-10-23 05:26:43 +00:00
}
2013-08-03 03:01:16 +00:00
public string [ ] GetFiles ( string path , SearchOption searchOption )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2012-01-23 06:43:11 +00:00
return Directory . GetFiles ( path , "*.*" , searchOption ) ;
2011-10-23 05:26:43 +00:00
}
2013-08-03 03:01:16 +00:00
public long GetFolderSize ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2011-10-23 05:26:43 +00:00
return GetFiles ( path , SearchOption . AllDirectories ) . Sum ( e = > new FileInfo ( e ) . Length ) ;
}
2013-08-03 03:01:16 +00:00
public long GetFileSize ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2012-10-20 01:42:42 +00:00
if ( ! FileExists ( path ) )
2013-09-13 04:59:29 +00:00
{
2012-10-20 01:42:42 +00:00
throw new FileNotFoundException ( "File doesn't exist: " + path ) ;
2013-09-13 04:59:29 +00:00
}
2012-10-20 01:42:42 +00:00
2011-10-23 05:26:43 +00:00
var fi = new FileInfo ( path ) ;
return fi . Length ;
}
2013-09-12 06:52:37 +00:00
public void CreateFolder ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-09-12 06:52:37 +00:00
Directory . CreateDirectory ( path ) ;
2011-10-23 05:26:43 +00:00
}
2013-08-03 03:01:16 +00:00
public void DeleteFile ( string path )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2011-11-20 05:35:44 +00:00
Logger . Trace ( "Deleting file: {0}" , path ) ;
2013-09-13 04:59:29 +00:00
RemoveReadOnly ( path ) ;
2011-10-23 05:26:43 +00:00
File . Delete ( path ) ;
}
2014-02-08 02:16:19 +00:00
public void CopyFile ( string source , string destination , bool overwrite = false )
{
2014-11-15 00:42:22 +00:00
Ensure . That ( source , ( ) = > source ) . IsValidPath ( ) ;
Ensure . That ( destination , ( ) = > destination ) . IsValidPath ( ) ;
2014-02-08 02:16:19 +00:00
2014-11-15 00:42:22 +00:00
if ( source . PathEquals ( destination ) )
{
throw new IOException ( string . Format ( "Source and destination can't be the same {0}" , source ) ) ;
}
2019-04-13 03:25:58 +00:00
CopyFileInternal ( source , destination , overwrite ) ;
}
protected virtual void CopyFileInternal ( string source , string destination , bool overwrite = false )
{
2014-11-15 00:42:22 +00:00
File . Copy ( source , destination , overwrite ) ;
2014-08-17 18:39:08 +00:00
}
2014-11-15 00:42:22 +00:00
public void MoveFile ( string source , string destination , bool overwrite = false )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( source , ( ) = > source ) . IsValidPath ( ) ;
Ensure . That ( destination , ( ) = > destination ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2013-08-20 19:28:46 +00:00
if ( source . PathEquals ( destination ) )
2011-11-18 07:16:05 +00:00
{
2014-11-15 00:42:22 +00:00
throw new IOException ( string . Format ( "Source and destination can't be the same {0}" , source ) ) ;
2011-11-18 07:16:05 +00:00
}
2019-12-23 21:50:52 +00:00
var destExists = FileExists ( destination ) ;
if ( destExists & & overwrite )
2011-12-14 08:06:54 +00:00
{
DeleteFile ( destination ) ;
}
2014-11-15 00:42:22 +00:00
RemoveReadOnly ( source ) ;
2019-12-23 21:50:52 +00:00
// NET Core is too eager to copy/delete if overwrite is false
// Therefore we also set overwrite if we know destination doesn't exist
MoveFileInternal ( source , destination , overwrite | | ! destExists ) ;
2011-10-23 05:26:43 +00:00
}
2018-02-02 12:23:29 +00:00
public void MoveFolder ( string source , string destination , bool overwrite = false )
{
Ensure . That ( source , ( ) = > source ) . IsValidPath ( ) ;
Ensure . That ( destination , ( ) = > destination ) . IsValidPath ( ) ;
if ( source . PathEquals ( destination ) )
{
throw new IOException ( string . Format ( "Source and destination can't be the same {0}" , source ) ) ;
}
if ( FolderExists ( destination ) & & overwrite )
{
DeleteFolder ( destination , true ) ;
}
RemoveReadOnlyFolder ( source ) ;
Directory . Move ( source , destination ) ;
}
2019-12-23 21:50:52 +00:00
protected virtual void MoveFileInternal ( string source , string destination , bool overwrite )
2019-04-13 03:25:58 +00:00
{
2019-12-23 21:50:52 +00:00
#if NETCOREAPP
File . Move ( source , destination , overwrite ) ;
#else
2019-04-13 03:25:58 +00:00
File . Move ( source , destination ) ;
2019-12-23 21:50:52 +00:00
#endif
2019-04-13 03:25:58 +00:00
}
2014-08-17 18:39:08 +00:00
public abstract bool TryCreateHardLink ( string source , string destination ) ;
2013-08-03 03:01:16 +00:00
public void DeleteFolder ( string path , bool recursive )
2011-10-23 05:26:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2014-04-19 15:09:22 +00:00
var files = Directory . GetFiles ( path , "*.*" , recursive ? SearchOption . AllDirectories : SearchOption . TopDirectoryOnly ) ;
Array . ForEach ( files , RemoveReadOnly ) ;
2011-10-23 05:26:43 +00:00
Directory . Delete ( path , recursive ) ;
}
2013-08-03 03:01:16 +00:00
public string ReadAllText ( string filePath )
2011-11-22 06:55:09 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( filePath , ( ) = > filePath ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2011-11-22 06:55:09 +00:00
return File . ReadAllText ( filePath ) ;
}
2011-12-10 19:22:47 +00:00
2013-08-03 03:01:16 +00:00
public void WriteAllText ( string filename , string contents )
2012-07-10 04:37:24 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( filename , ( ) = > filename ) . IsValidPath ( ) ;
2013-09-13 04:59:29 +00:00
RemoveReadOnly ( filename ) ;
2012-07-10 04:37:24 +00:00
File . WriteAllText ( filename , contents ) ;
}
2011-12-10 19:22:47 +00:00
2014-10-14 21:31:35 +00:00
public void FolderSetLastWriteTime ( string path , DateTime dateTime )
2012-09-04 06:49:04 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2018-03-04 14:42:15 +00:00
if ( dateTime . Before ( DateTimeExtensions . Epoch ) )
{
dateTime = DateTimeExtensions . Epoch ;
}
2012-09-04 06:49:04 +00:00
Directory . SetLastWriteTimeUtc ( path , dateTime ) ;
}
2012-10-20 08:01:47 +00:00
2014-03-08 19:01:51 +00:00
public void FileSetLastWriteTime ( string path , DateTime dateTime )
{
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2019-12-22 21:24:11 +00:00
2018-03-04 14:42:15 +00:00
if ( dateTime . Before ( DateTimeExtensions . Epoch ) )
{
dateTime = DateTimeExtensions . Epoch ;
}
2014-03-08 19:01:51 +00:00
File . SetLastWriteTime ( path , dateTime ) ;
}
2014-07-31 19:33:56 +00:00
2013-09-12 06:52:37 +00:00
public bool IsFileLocked ( string file )
2012-10-20 08:01:47 +00:00
{
try
{
2013-09-13 04:59:29 +00:00
using ( File . Open ( file , FileMode . Open , FileAccess . Read , FileShare . None ) )
{
return false ;
}
2012-10-20 08:01:47 +00:00
}
catch ( IOException )
{
return true ;
}
}
2013-08-03 03:01:16 +00:00
public string GetPathRoot ( string path )
2012-12-24 07:16:43 +00:00
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-05-24 22:18:37 +00:00
2012-12-24 07:16:43 +00:00
return Path . GetPathRoot ( path ) ;
}
2013-07-05 06:30:45 +00:00
2013-11-19 06:25:02 +00:00
public string GetParentFolder ( string path )
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-11-19 06:25:02 +00:00
2015-02-14 00:52:42 +00:00
var parent = Directory . GetParent ( path . TrimEnd ( Path . DirectorySeparatorChar ) ) ;
2013-11-19 06:25:02 +00:00
if ( parent = = null )
{
return null ;
}
return parent . FullName ;
}
2013-08-13 00:22:35 +00:00
public void SetPermissions ( string filename , WellKnownSidType accountSid , FileSystemRights rights , AccessControlType controlType )
2013-07-05 06:30:45 +00:00
{
2013-07-26 05:55:19 +00:00
try
{
2013-08-13 00:22:35 +00:00
var sid = new SecurityIdentifier ( accountSid , null ) ;
2013-07-05 06:30:45 +00:00
2013-07-26 05:55:19 +00:00
var directoryInfo = new DirectoryInfo ( filename ) ;
2016-03-20 17:54:02 +00:00
var directorySecurity = directoryInfo . GetAccessControl ( AccessControlSections . Access ) ;
var rules = directorySecurity . GetAccessRules ( true , false , typeof ( SecurityIdentifier ) ) ;
if ( rules . OfType < FileSystemAccessRule > ( ) . Any ( acl = > acl . AccessControlType = = controlType & & ( acl . FileSystemRights & rights ) = = rights & & acl . IdentityReference . Equals ( sid ) ) )
{
return ;
}
2013-07-26 05:55:19 +00:00
2013-08-13 00:22:35 +00:00
var accessRule = new FileSystemAccessRule ( sid , rights ,
2013-07-26 05:55:19 +00:00
InheritanceFlags . ContainerInherit | InheritanceFlags . ObjectInherit ,
2016-03-20 17:54:02 +00:00
PropagationFlags . InheritOnly , controlType ) ;
2013-07-26 05:55:19 +00:00
2016-03-20 17:54:02 +00:00
bool modified ;
directorySecurity . ModifyAccessRule ( AccessControlModification . Add , accessRule , out modified ) ;
if ( modified )
{
directoryInfo . SetAccessControl ( directorySecurity ) ;
}
2013-07-26 05:55:19 +00:00
}
catch ( Exception e )
{
2016-03-20 17:54:02 +00:00
Logger . Warn ( e , "Couldn't set permission for {0}. account:{1} rights:{2} accessControlType:{3}" , filename , accountSid , rights , controlType ) ;
2013-07-26 05:55:19 +00:00
throw ;
}
2013-07-05 06:30:45 +00:00
}
2013-07-23 00:50:37 +00:00
2013-09-13 04:59:29 +00:00
private static void RemoveReadOnly ( string path )
{
if ( File . Exists ( path ) )
{
2014-03-21 05:42:31 +00:00
var attributes = File . GetAttributes ( path ) ;
if ( attributes . HasFlag ( FileAttributes . ReadOnly ) )
{
var newAttributes = attributes & ~ ( FileAttributes . ReadOnly ) ;
File . SetAttributes ( path , newAttributes ) ;
}
2013-09-13 04:59:29 +00:00
}
}
2018-02-02 12:23:29 +00:00
private static void RemoveReadOnlyFolder ( string path )
{
if ( Directory . Exists ( path ) )
{
var dirInfo = new DirectoryInfo ( path ) ;
if ( dirInfo . Attributes . HasFlag ( FileAttributes . ReadOnly ) )
{
var newAttributes = dirInfo . Attributes & ~ ( FileAttributes . ReadOnly ) ;
dirInfo . Attributes = newAttributes ;
}
}
}
2013-07-30 00:09:48 +00:00
public FileAttributes GetFileAttributes ( string path )
{
return File . GetAttributes ( path ) ;
}
2013-09-08 17:13:46 +00:00
public void EmptyFolder ( string path )
{
2013-11-30 23:53:07 +00:00
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
2013-09-08 17:13:46 +00:00
foreach ( var file in GetFiles ( path , SearchOption . TopDirectoryOnly ) )
{
DeleteFile ( file ) ;
}
foreach ( var directory in GetDirectories ( path ) )
{
DeleteFolder ( directory , true ) ;
}
}
2013-10-11 08:49:03 +00:00
public string [ ] GetFixedDrives ( )
{
2015-12-30 15:22:41 +00:00
return GetMounts ( ) . Where ( x = > x . DriveType = = DriveType . Fixed ) . Select ( x = > x . RootDirectory ) . ToArray ( ) ;
2013-10-11 08:49:03 +00:00
}
2013-10-16 04:11:45 +00:00
public string GetVolumeLabel ( string path )
{
2015-12-30 15:22:41 +00:00
var driveInfo = GetMounts ( ) . SingleOrDefault ( d = > d . RootDirectory . PathEquals ( path ) ) ;
2013-10-16 04:11:45 +00:00
if ( driveInfo = = null )
{
return null ;
}
return driveInfo . VolumeLabel ;
}
2014-04-28 06:34:29 +00:00
2015-01-22 22:12:35 +00:00
public FileStream OpenReadStream ( string path )
2014-04-28 06:34:29 +00:00
{
if ( ! FileExists ( path ) )
{
throw new FileNotFoundException ( "Unable to find file: " + path , path ) ;
}
2014-09-03 10:32:34 +00:00
return new FileStream ( path , FileMode . Open , FileAccess . Read ) ;
2014-04-28 06:34:29 +00:00
}
2014-12-16 07:28:55 +00:00
2015-01-22 22:12:35 +00:00
public FileStream OpenWriteStream ( string path )
{
return new FileStream ( path , FileMode . Create ) ;
}
2019-04-13 03:25:58 +00:00
public List < IMount > GetMounts ( )
{
return GetAllMounts ( ) . Where ( d = > ! IsSpecialMount ( d ) ) . ToList ( ) ;
}
protected virtual List < IMount > GetAllMounts ( )
2015-12-30 15:22:41 +00:00
{
2016-07-27 05:40:54 +00:00
return GetDriveInfoMounts ( ) . Where ( d = > d . DriveType = = DriveType . Fixed | | d . DriveType = = DriveType . Network | | d . DriveType = = DriveType . Removable )
. Select ( d = > new DriveInfoMount ( d ) )
. Cast < IMount > ( )
. ToList ( ) ;
2015-12-30 15:22:41 +00:00
}
2019-04-13 03:25:58 +00:00
protected virtual bool IsSpecialMount ( IMount mount )
{
return false ;
}
2015-12-30 15:22:41 +00:00
public virtual IMount GetMount ( string path )
{
2016-02-11 00:13:07 +00:00
try
{
2019-04-13 03:25:58 +00:00
var mounts = GetAllMounts ( ) ;
2015-12-30 15:22:41 +00:00
2016-02-11 00:13:07 +00:00
return mounts . Where ( drive = > drive . RootDirectory . PathEquals ( path ) | |
drive . RootDirectory . IsParentPath ( path ) )
. OrderByDescending ( drive = > drive . RootDirectory . Length )
. FirstOrDefault ( ) ;
}
catch ( Exception ex )
{
2016-02-11 21:13:42 +00:00
Logger . Debug ( ex , string . Format ( "Failed to get mount for path {0}" , path ) ) ;
2016-02-11 00:13:07 +00:00
return null ;
}
2015-12-30 15:22:41 +00:00
}
2016-07-27 05:40:54 +00:00
protected List < DriveInfo > GetDriveInfoMounts ( )
2014-12-20 21:24:29 +00:00
{
return DriveInfo . GetDrives ( )
2015-07-17 21:51:33 +00:00
. Where ( d = > d . IsReady )
2014-12-20 21:24:29 +00:00
. ToList ( ) ;
}
2014-12-16 07:28:55 +00:00
public List < DirectoryInfo > GetDirectoryInfos ( string path )
{
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
var di = new DirectoryInfo ( path ) ;
return di . GetDirectories ( ) . ToList ( ) ;
}
public List < FileInfo > GetFileInfos ( string path )
{
Ensure . That ( path , ( ) = > path ) . IsValidPath ( ) ;
var di = new DirectoryInfo ( path ) ;
return di . GetFiles ( ) . ToList ( ) ;
}
2016-02-11 08:38:44 +00:00
public void RemoveEmptySubfolders ( string path )
{
var subfolders = GetDirectories ( path ) ;
var files = GetFiles ( path , SearchOption . AllDirectories ) ;
foreach ( var subfolder in subfolders )
{
if ( files . None ( f = > subfolder . IsParentPath ( f ) ) )
{
2016-02-11 08:54:52 +00:00
DeleteFolder ( subfolder , false ) ;
2016-02-11 08:38:44 +00:00
}
}
}
2018-11-23 07:03:32 +00:00
public void SaveStream ( Stream stream , string path )
{
using ( var fileStream = OpenWriteStream ( path ) )
{
stream . CopyTo ( fileStream ) ;
}
}
2011-10-23 05:26:43 +00:00
}
2014-01-06 06:20:08 +00:00
}