Skip to content

Instantly share code, notes, and snippets.

@Dkowald
Last active October 10, 2019 04:24
Show Gist options
  • Save Dkowald/df49cda62ea033be1eda60333921675a to your computer and use it in GitHub Desktop.
Save Dkowald/df49cda62ea033be1eda60333921675a to your computer and use it in GitHub Desktop.
Extensions so FileInfo and DirectoryInfo include functions from Path and File
using System;
using System.IO;
using System.Linq;
namespace kwd.gist
{
/// <summary>
/// Extensions for <see cref="DirectoryInfo"/> to include missing functions from <see cref="Directory"/>.
/// </summary>
public static class DirectoryInfoDirectoryExtensions
{
/// <summary>Moves a <see cref="T:System.IO.DirectoryInfo"></see> instance and its contents to a new path.</summary>
public static void MoveTo(this DirectoryInfo src, DirectoryInfo destDir) =>
// ReSharper disable once AssignNullToNotNullAttribute
src?.MoveTo(destDir?.FullName);
/// <summary>
/// See <see cref="Directory.SetCurrentDirectory(string)"/> <br />
/// Sets the application&amp;#39;s current working directory to the specified directory.
/// </summary>
public static void SetCurrentDirectory(this DirectoryInfo path) =>
Directory.SetCurrentDirectory(path?.FullName ?? throw new ArgumentNullException(nameof(path)));
/// <summary>
/// Get a child path (without create)
/// </summary>
public static DirectoryInfo Get(this DirectoryInfo dir, params string[] path) =>
new DirectoryInfo(Path.Combine(
new[]{dir?.FullName ?? throw new ArgumentNullException(nameof(dir))}
.Union(path).ToArray()));
}
}
using System;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Internal;
namespace kwd.gist
{
/// <summary>
/// Extensions for <see cref="FileInfo"/> and <see cref="DirectoryInfo"/>
/// </summary>
public static class FileDirectoryExtensions
{
/// <summary>
/// Move existing file to specified directory, optionally overwriting target if it exists.
/// </summary>
public static FileInfo MoveTo(this FileInfo file, DirectoryInfo dir, bool overwrite = false)
{
if (file == null) throw new ArgumentNullException(nameof(file));
if (dir == null) throw new ArgumentNullException(nameof(dir));
var result = new FileInfo(Path.Combine(dir.FullName, file.Name));
if (result.Exists && overwrite) { result.Delete(); }
File.Move(file.FullName, result.FullName);
return result;
}
/// <summary>
/// Copy existing file to specific directory, optionally overwriting target if it exists.
/// </summary>
public static FileInfo CopyTo(this FileInfo file, DirectoryInfo dir, bool overwrite = false)
{
if (file == null) throw new ArgumentNullException(nameof(file));
if (dir == null) throw new ArgumentNullException(nameof(dir));
var result = new FileInfo(Path.Combine(dir.FullName, file.Name));
//Create folder if need.
file.Refresh();
if(file.Exists) { result.Directory?.Create(); }
File.Copy(file.FullName, result.FullName, overwrite);
return result;
}
/// <summary>
/// Set the file LastWrite to current time; creating the file if needed.
/// </summary>
public static FileInfo Touch(this FileInfo file, ISystemClock? clock = null)
{
if (file == null) throw new ArgumentNullException(nameof(file));
file.Refresh();
if (!file.Exists)
{
file.Directory?.Create();
file.Create().Dispose();
}
if (clock != null)
{ file.LastWriteTimeUtc = clock.UtcNow.UtcDateTime; }
return file;
}
/// <summary>
/// Sets the directory LastWrite to current time; creating if needed.
/// </summary>
public static DirectoryInfo Touch(this DirectoryInfo dir, ISystemClock? clock = null)
{
if (dir == null) throw new ArgumentNullException(nameof(dir));
dir.Refresh();
if (!dir.Exists) { dir.Create(); }
if (clock != null)
{ dir.LastWriteTimeUtc = clock.UtcNow.UtcDateTime; }
return dir;
}
/// <summary>
/// Removes the directory and all its content (files and directories).
/// </summary>
public static DirectoryInfo EnsureDelete(this DirectoryInfo dir)
{
if (dir == null) throw new ArgumentNullException(nameof(dir));
dir.Refresh();
if (dir.Exists) { dir.Delete(true);}
return dir;
}
/// <summary>
/// Remove a file.
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public static FileInfo EnsureDelete(this FileInfo file)
{
if(file == null) throw new ArgumentNullException(nameof(file));
file.Refresh();
if (file.Exists) { file.Delete(); file.Refresh();}
return file;
}
/// <summary>
/// Get child file info.
/// </summary>
public static FileInfo GetFile(this DirectoryInfo dir, params string[] subPath)
{
if (dir == null) {throw new ArgumentNullException(nameof(dir));}
if (subPath?.Any() != true) { throw new ArgumentNullException(nameof(subPath));}
var path = Path.Combine(dir.FullName, Path.Combine(subPath));
return new FileInfo(path);
}
/// <summary>
/// Get child folder.
/// </summary>
public static DirectoryInfo GetFolder(this DirectoryInfo dir, params string[] subPath)
{
if (dir == null) {throw new ArgumentNullException(nameof(dir));}
if (subPath?.Any() != true) { return dir; }
var path = Path.Combine(dir.FullName, Path.Combine(subPath));
return new DirectoryInfo(path);
}
/// <summary>
/// Delete child folders that contain no files.
/// </summary>
public static DirectoryInfo Prune(this DirectoryInfo dir)
{
if (dir == null) throw new ArgumentNullException();
void RecursivePrune(DirectoryInfo subDir)
{
subDir.Refresh();
if (!subDir.Exists) { return; }
foreach (var subSubDir in subDir.GetDirectories())
{
RecursivePrune(subSubDir);
}
if (!subDir.GetFileSystemInfos().Any()) { subDir.Delete();}
}
RecursivePrune(dir);
return dir;
}
}
}
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace kwd.gist
{
/// <summary>
/// Extensions for <see cref="FileInfo"/> to include missing function from <see cref="File"/>.
/// </summary>
public static class FileInfoFileExtensions
{
///<summary>
/// See <see cref="File.AppendAllLines(string, IEnumerable{string})"/> <br />
/// Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file.
/// </summary>
public static void AppendAllLines(this FileInfo fileInfo, IEnumerable<string> contents)
=> File.AppendAllLines(fileInfo?.FullName, contents);
/// <summary>
/// See <see cref="File.AppendAllLines(string, IEnumerable{string}, Encoding)"/> <br />
/// Appends lines to a file by using a specified encoding, and then closes the file. If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file.
/// </summary>
public static void AppendAllLines(this FileInfo fileInfo, IEnumerable<string> contents, Encoding encoding)
=> File.AppendAllLines(fileInfo?.FullName, contents, encoding);
/// <summary>
/// See <see cref="File.AppendAllLinesAsync(string, IEnumerable{string}, CancellationToken)"/>
/// </summary>
public static Task AppendAllLinesAsync(this FileInfo fileInfo, IEnumerable<string> contents,
CancellationToken cancellationToken = default(CancellationToken))
=> File.AppendAllLinesAsync(fileInfo?.FullName, contents, cancellationToken);
/// <summary>
/// See <see cref="File.AppendAllLinesAsync(string, IEnumerable{string}, Encoding, CancellationToken)"/>
/// </summary>
public static Task AppendAllLinesAsync(this FileInfo fileInfo, IEnumerable<string> contents, Encoding encoding,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.AppendAllLinesAsync(fileInfo?.FullName, contents, encoding, cancellationToken);
/// <summary>
/// See <see cref="File.AppendAllText(string, string)"/> <br />
/// Opens a file, appends the specified string to the file, and then closes the file. If the file does not exist, this method creates a file, writes the specified string to the file, then closes the file.
/// </summary>
public static void AppendAllText(this FileInfo fileInfo, string contents) =>
File.AppendAllText(fileInfo?.FullName, contents);
/// <summary>
/// See <see cref="File.AppendAllText(string, string, Encoding)"/> <br />
/// Appends the specified string to the file, creating the file if it does not already exist.
/// </summary>
public static void AppendAllText(this FileInfo fileInfo, string contents, Encoding encoding) =>
File.AppendAllText(fileInfo?.FullName, contents, encoding);
/// <summary>
/// See <see cref="File.AppendAllTextAsync(string,string,System.Threading.CancellationToken)"/>
/// </summary>
public static Task AppendAllTextAsync(this FileInfo fileInfo, string contents,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.AppendAllTextAsync(fileInfo?.FullName, contents, cancellationToken);
/// <summary>
/// See <see cref="File.AppendAllTextAsync(string, string, Encoding, CancellationToken)"/>
/// </summary>
public static Task AppendAllTextAsync(this FileInfo fileInfo, string contents, Encoding encoding,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.AppendAllTextAsync(fileInfo?.FullName, contents, encoding, cancellationToken);
/// <summary>
/// See <see cref="File.AppendText(string)"/> <br />
/// Creates a <see cref="T:System.IO.StreamWriter"></see> that appends UTF-8 encoded text to an existing file, or to a new file if the specified file does not exist.
/// </summary>
public static StreamWriter AppendText(this FileInfo fileInfo) =>
File.AppendText(fileInfo?.FullName);
/// <summary>
/// See <see cref="File.ReadAllBytes(string)"/> <br />
/// Opens a binary file, reads the contents of the file into a byte array, and then closes the file.</summary>
public static byte[] ReadAllBytes(this FileInfo fileInfo) =>
File.ReadAllBytes(fileInfo?.FullName);
/// <summary>
/// See <see cref="File.ReadAllBytesAsync(string, CancellationToken)"/>
/// </summary>
public static Task<byte[]> ReadAllBytesAsync(this FileInfo fileInfo,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.ReadAllBytesAsync(fileInfo?.FullName, cancellationToken);
/// <summary>
/// See <see cref="File.ReadAllLines(string)"/> <br />
/// Opens a text file, reads all lines of the file, and then closes the file.
/// </summary>
public static string[] ReadAllLines(this FileInfo fileInfo) =>
File.ReadAllLines(fileInfo?.FullName);
/// <summary>
/// See <see cref="File.ReadAllLines(string, Encoding)"/> <br />
/// Opens a file, reads all lines of the file with the specified encoding, and then closes the file.
/// </summary>
public static string[] ReadAllLines(this FileInfo fileInfo, Encoding encoding) =>
File.ReadAllLines(fileInfo?.FullName, encoding);
/// <summary>
/// See <see cref="File.ReadAllLinesAsync(string, CancellationToken)"/>
/// </summary>
public static Task<string[]> ReadAllLinesAsync(this FileInfo fileInfo,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.ReadAllLinesAsync(fileInfo?.FullName, cancellationToken);
/// <summary>
/// See <see cref="File.ReadAllLinesAsync(string, Encoding, CancellationToken)"/>
/// </summary>
public static Task<string[]> ReadAllLinesAsync(this FileInfo fileInfo, Encoding encoding,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.ReadAllLinesAsync(fileInfo?.FullName, encoding, cancellationToken);
/// <summary>
/// See <see cref="File.ReadAllText(string)"/> <br />
/// Opens a text file, reads all lines of the file, and then closes the file.
/// </summary>
public static string ReadAllText(this FileInfo fileInfo) =>
File.ReadAllText(fileInfo?.FullName);
/// <summary>
/// See <see cref="File.ReadAllText(string, Encoding)"/> <br />
/// Opens a file, reads all lines of the file with the specified encoding, and then closes the file.
/// </summary>
public static string ReadAllText(this FileInfo fileInfo, Encoding encoding) =>
File.ReadAllText(fileInfo?.FullName, encoding);
/// <summary>
/// See <see cref="File.ReadAllTextAsync(string, CancellationToken)"/>
/// </summary>
public static Task<string> ReadAllTextAsync(this FileInfo fileInfo,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.ReadAllTextAsync(fileInfo?.FullName, cancellationToken);
/// <summary>
/// See <see cref="File.ReadAllText(string, Encoding)"/>
/// </summary>
public static Task<string> ReadAllTextAsync(this FileInfo fileInfo, Encoding encoding,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.ReadAllTextAsync(fileInfo?.FullName, encoding, cancellationToken);
/// <summary>
/// See <see cref="File.ReadAllLines(string)"/><br/>
/// Reads the lines of a file.
/// </summary>
public static IEnumerable<string> ReadLines(this FileInfo fileInfo) =>
File.ReadLines(fileInfo?.FullName);
/// <summary>
/// See <see cref="File.ReadAllLines(string, Encoding)"/> <br/>
/// Read the lines of a file that has a specified encoding.
/// </summary>
public static IEnumerable<string> ReadLines(this FileInfo fileInfo, Encoding encoding) =>
File.ReadLines(fileInfo?.FullName, encoding);
/// <summary>
/// See <see cref="File.WriteAllBytes(string, byte[])"/> <br />
/// Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.
/// </summary>
public static void WriteAllBytes(this FileInfo fileInfo, byte[] bytes) =>
File.WriteAllBytes(fileInfo?.FullName, bytes);
/// <summary>
/// See <see cref="File.WriteAllBytesAsync(string, byte[], CancellationToken)"/>
/// </summary>
public static Task WriteAllBytesAsync(this FileInfo fileInfo, byte[] bytes,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.WriteAllBytesAsync(fileInfo?.FullName, bytes, cancellationToken);
/// <summary>
/// See <see cref="File.WriteAllLines(string,string[])"/> <br />
/// Creates a new file, write the specified string array to the file, and then closes the file.
/// </summary>
public static void WriteAllLines(this FileInfo fileInfo, string[] contents) =>
File.WriteAllLines(fileInfo?.FullName, contents);
/// <summary>
/// See <see cref="File.WriteAllLines(string,IEnumerable{string})"/> <br />
/// Creates a new file, writes a collection of strings to the file, and then closes the file.
/// </summary>
public static void WriteAllLines(this FileInfo fileInfo, IEnumerable<string> contents) =>
File.WriteAllLines(fileInfo?.FullName, contents);
/// <summary>
/// See <see cref="File.WriteAllLines(string,string[], Encoding)"/> <br />
/// Creates a new file, writes the specified string array to the file by using the specified encoding, and then closes the file.
/// </summary>
public static void WriteAllLines(this FileInfo fileInfo, string[] contents, Encoding encoding) =>
File.WriteAllLines(fileInfo?.FullName, contents, encoding);
/// <summary>
/// See <see cref="File.WriteAllLines(string, string[], Encoding)"/> <br />
/// Creates a new file by using the specified encoding, writes a collection of strings to the file, and then closes the file.
/// </summary>
public static void WriteAllLines(this FileInfo fileInfo, IEnumerable<string> contents, Encoding encoding) =>
File.WriteAllLines(fileInfo?.FullName, contents, encoding);
/// <summary>
/// See <see cref="File.WriteAllLinesAsync(string, IEnumerable{string}, CancellationToken)"/>
/// </summary>
public static Task WriteAllLinesAsync(this FileInfo fileInfo, IEnumerable<string> contents,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.WriteAllLinesAsync(fileInfo?.FullName, contents, cancellationToken);
/// <summary>
/// See <see cref="File.WriteAllLinesAsync(string, IEnumerable{string}, Encoding, CancellationToken)"/>
/// </summary>
public static Task WriteAllLinesAsync(this FileInfo fileInfo, IEnumerable<string> contents, Encoding encoding,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.WriteAllLinesAsync(fileInfo?.FullName, contents, encoding, cancellationToken);
/// <summary>
/// See <see cref="File.WriteAllText(string,string)"/> <br />
/// Creates a new file, writes the specified string to the file, and then closes the file. If the target file already exists, it is overwritten.
/// </summary>
public static void WriteAllText(this FileInfo fileInfo, string contents) =>
File.WriteAllText(fileInfo?.FullName, contents);
/// <summary>
/// See <see cref="File.WriteAllText(string,string, Encoding)"/> <br />
/// Creates a new file, writes the specified string to the file using the specified encoding, and then closes the file. If the target file already exists, it is overwritten.
/// </summary>
public static void WriteAllText(this FileInfo fileInfo, string contents, Encoding encoding) =>
File.WriteAllText(fileInfo?.FullName, contents, encoding);
/// <summary>
/// See <see cref="File.WriteAllTextAsync(string, string, CancellationToken)"/>
/// </summary>
public static Task WriteAllTextAsync(this FileInfo fileInfo, string contents,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.WriteAllTextAsync(fileInfo?.FullName, contents, cancellationToken);
/// <summary>
/// See <see cref="File.WriteAllTextAsync(string,string, Encoding, CancellationToken)"/>
/// </summary>
public static Task WriteAllTextAsync(this FileInfo fileInfo, string contents, Encoding encoding,
CancellationToken cancellationToken = default(CancellationToken)) =>
File.WriteAllTextAsync(fileInfo?.FullName, contents, encoding, cancellationToken);
}
}
using System;
using System.IO;
namespace kwd.gist
{
/// <summary>
/// Extensions for <see cref="FileInfo"/> to include missing functions from <see cref="Path"/>.
/// </summary>
public static class FileInfoPathExtensions
{
/// <summary>
/// See <see cref="Path.ChangeExtension(string, string)"/> <br />
/// Changes the extension of a path string.
/// </summary>
public static FileInfo ChangeExtension(this FileInfo item, string extension) =>
new FileInfo(Path.ChangeExtension(item?.FullName, extension));
/// <summary>
/// See <see cref="Path.GetExtension(string)"/>
/// Returns the extension of the specified path string.
/// </summary>
public static string? GetExtension(this FileInfo item) =>
Path.GetExtension(item?.FullName);
/// <summary>
/// See <see cref="Path.GetFileNameWithoutExtension(string)"/>
/// Returns the file name of the specified path string without the extension.
/// </summary>
public static string? GetFileNameWithoutExtension(this FileInfo item) =>
Path.GetFileNameWithoutExtension(item?.FullName);
/// <summary>
/// See <see cref="Path.GetPathRoot(string)"/> <br />
/// Gets the root directory information of the specified path.
/// </summary>
public static DirectoryInfo GetPathRoot(this FileInfo item) =>
new DirectoryInfo(Path.GetPathRoot(item?.FullName));
/// <summary>
/// See <see cref="Path.HasExtension(string)"/> < br />
/// Determines whether a path includes a file name extension.
/// </summary>
public static bool HasExtension(this FileInfo item) =>
Path.HasExtension(item?.FullName);
/// <summary>
/// See <see cref="Path.GetRelativePath(string, string)"/>
/// </summary>
public static string GetRelativePath(this FileInfo item, string relativeTo) =>
Path.GetRelativePath(relativeTo ?? "",
item?.FullName ?? throw new ArgumentNullException(nameof(relativeTo)));
/// <summary>
/// See <see cref="Path.GetRelativePath(string, string)"/>
/// </summary>
public static string GetRelativePath(this DirectoryInfo item, string relativeTo) =>
Path.GetRelativePath(relativeTo ?? "",
item?.FullName ?? throw new ArgumentNullException(nameof(relativeTo)));
/// <summary>
/// See <see cref="Path.GetRelativePath(string, string)"/>
/// </summary>
public static string GetRelativePath(this FileInfo item, DirectoryInfo relativeTo) =>
Path.GetRelativePath(relativeTo?.FullName ?? throw new ArgumentNullException(nameof(relativeTo)),
item?.FullName ?? throw new ArgumentNullException(nameof(item)));
/// <summary>
/// See <see cref="Path.GetRelativePath(string, string)"/>
/// </summary>
public static string GetRelativePath(this DirectoryInfo item, DirectoryInfo relativeTo) =>
Path.GetRelativePath(relativeTo?.FullName ?? throw new ArgumentNullException(nameof(relativeTo)),
item?.FullName ?? throw new ArgumentNullException(nameof(item)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment