using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using Core.Common.Utils.Properties;
using log4net;
namespace Core.Common.Utils.IO
{
///
/// File manipulations
///
public static class FileUtils
{
private static readonly ILog Log = LogManager.GetLogger(typeof(FileUtils));
///
/// Copies the source file to the target destination; if the file
/// already exists, it will be overwritten by default.
///
/// Source file path.
/// Destination file path.
/// True if the destination file should be overwritten when it exists, false otherwise.
public static void CopyFile(string sourcePath, string targetPath, bool overwrite = true)
{
var sourceFullPath = Path.GetFullPath(sourcePath);
var targetFullPath = Path.GetFullPath(targetPath);
if (sourceFullPath == targetFullPath)
{
return;
}
if (File.Exists(targetPath))
{
if (!overwrite)
{
return;
}
File.Delete(targetPath);
}
File.Copy(sourcePath, targetPath);
}
///
/// Copy files in a directory (and its subdirectories) to another directory.
///
/// Source directory.
/// Destination directory.
/// Exclude folder from being copied.
public static void CopyAll(DirectoryInfo source, DirectoryInfo target, string ignorePath = "")
{
foreach (var diSourceSubDir in source.GetDirectories().Where(diSourceSubDir => diSourceSubDir.Name != ignorePath))
{
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
var nextTargetSubDir = target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir, ignorePath);
}
foreach (var fi in source.GetFiles())
{
Log.DebugFormat(Resource.FileUtils_CopyAll_Copying_0_1_, target.FullName, fi.Name);
if (!target.Exists)
{
target.Create();
}
var path = Path.Combine(target.ToString(), fi.Name);
fi.CopyTo(path, true);
}
}
///
/// Make all files and sub-directories writable.
///
///
public static void MakeWritable(string path)
{
if (Directory.Exists(path))
{
File.SetAttributes(path, FileAttributes.Normal);
}
var di = new DirectoryInfo(path);
foreach (DirectoryInfo di2 in di.GetDirectories())
{
File.SetAttributes(path, FileAttributes.Normal);
MakeWritable(Path.Combine(path, di2.Name));
}
// Copy each file into it's new directory.
foreach (FileInfo fi in di.GetFiles())
{
String filePath = Path.Combine(path, fi.Name);
File.SetAttributes(filePath, FileAttributes.Normal);
}
}
///
/// Check if the search item path is a subdirectory of the .
///
/// Directory path.
/// Name of the supposed child directory.
/// True if is a direct child of , false otherwise.
public static bool IsSubdirectory(string rootDir, string searchItem)
{
if (rootDir.StartsWith(@"\\")) //network disk?
{
return searchItem.StartsWith(rootDir, StringComparison.InvariantCultureIgnoreCase);
}
var rootDirAbsolute = AppendDirectorySeparatorIfMissing(Path.GetFullPath(rootDir));
var searchDirAbsolute = AppendDirectorySeparatorIfMissing(Path.GetFullPath(searchItem));
return searchDirAbsolute.Length > rootDirAbsolute.Length && searchDirAbsolute.StartsWith(rootDirAbsolute, StringComparison.InvariantCultureIgnoreCase);
}
///
/// Ensures a closing directory separator in .
///
/// Directory to ensure closing directory separator.
/// with closing directory separator.
public static string AppendDirectorySeparatorIfMissing(string directory)
{
if (!directory.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
directory += Path.DirectorySeparatorChar;
}
return directory;
}
///
/// Compares two directory strings.
///
/// Directory path.
/// Directory path to compare.
/// True if the string paths are equal.
public static bool CompareDirectories(string rootDir, string searchItem)
{
var root = Path.GetFullPath(rootDir);
var search = Path.GetFullPath(searchItem);
return root == search;
}
///
/// Returns a relative path string from a full path.
///
/// Directory path.
/// Directory path to make relative to .
/// Relative path from .
public static string GetRelativePath(string rootDir, string filePath)
{
if (rootDir == null || filePath == null)
{
return filePath;
}
if (rootDir.StartsWith("\\\\") && IsSubdirectory(rootDir, filePath)) //network disk?
{
return "." + filePath.Substring(rootDir.Length);
}
try
{
// Folders must end in a slash
rootDir = AppendDirectorySeparatorIfMissing(rootDir);
var folderUri = new Uri(rootDir);
var pathUri = new Uri(filePath);
return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
catch (Exception)
{
// gulp: return original filepath
}
return filePath;
}
///
/// Create dir if not exists.
///
/// File path to a directory.
/// Optional flag to delete the specified directory if it does exist when set to true.
/// When:
/// The directory specified by is read-only
/// Furthermore when is true:
/// A file with the same name and location specified by exists. -or-
/// The directory is the application's current working directory.
///
/// When: The caller does not have the required permission.
///
/// is a zero-length string, contains only white space, or contains one or more invalid characters as defined by . -or-
/// is prefixed with, or contains only a colon character (:).
/// is null.
///
/// The specified path, file name, or both exceed the system-defined maximum length.
/// For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters.
/// The specified path is invalid (for example, it is on an unmapped drive).
/// contains a colon character (:) that is not part of a drive label ("C:\").
public static void CreateDirectoryIfNotExists(string path, bool deleteIfExists = false)
{
if (Directory.Exists(path))
{
//replace the directory with a one
if (deleteIfExists)
{
Directory.Delete(path, true);
Directory.CreateDirectory(path);
}
}
else
{
Directory.CreateDirectory(path);
}
}
///
/// Initializes filesystemwatcher.
///
///
public static FileSystemWatcher CreateWatcher()
{
// use built-in filesystemwatcher class to monitor creation/modification/deletion of files
// example http://www.codeguru.com/csharp/csharp/cs_network/article.php/c6043/
var watcher = new FileSystemWatcher
{
IncludeSubdirectories = false,
NotifyFilter = NotifyFilters.FileName |
NotifyFilters.LastWrite |
NotifyFilters.Size
};
return watcher;
}
///
/// Checks wether the path is a valid relative path.
///
///
///
public static bool PathIsRelative(string path)
{
return !Path.IsPathRooted(path);
}
///
/// Replaces text in a file.
///
/// Path of the text file.
/// Text to search for.
/// Text to replace the search text.
public static void ReplaceInFile(string filePath, string searchText, string replaceText)
{
var reader = new StreamReader(filePath);
string content = reader.ReadToEnd();
reader.Close();
content = Regex.Replace(content, searchText, replaceText);
var writer = new StreamWriter(filePath);
writer.Write(content);
writer.Close();
}
///
/// Creates a temporary directory.
///
/// Path to temporary directory.
public static string CreateTempDirectory()
{
string path = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), path));
return Path.Combine(Path.GetTempPath(), path);
}
///
/// Check if the content of two files are equal.
///
/// First file path.
/// Second file path.
///
public static bool FilesAreEqual(string file1Path, string file2Path)
{
var first = new FileInfo(file1Path);
var second = new FileInfo(file2Path);
if (first.Length != second.Length)
{
return false;
}
const int bytesToRead = sizeof(Int64);
var iterations = (int) Math.Ceiling((double) first.Length/bytesToRead);
using (FileStream fs1 = first.OpenRead())
{
using (FileStream fs2 = second.OpenRead())
{
var one = new byte[bytesToRead];
var two = new byte[bytesToRead];
for (int i = 0; i < iterations; i++)
{
fs1.Read(one, 0, bytesToRead);
fs2.Read(two, 0, bytesToRead);
if (BitConverter.ToInt64(one, 0) != BitConverter.ToInt64(two, 0))
{
return false;
}
}
}
}
return true;
}
///
/// Checks if the extension of a file belongs to the .
///
/// "My file format1 (*.ext1)|*.ext1|My file format2 (*.ext2)|*.ext2".
/// Path to a file or filename including extension.
///
public static bool FileMatchesFileFilterByExtension(string fileFilter, string path)
{
if (String.IsNullOrEmpty(Path.GetExtension(path)))
{
return false;
}
return Regex.Match(fileFilter, String.Format(@"(\||\;)+\s*\*\{0}", Path.GetExtension(path))).Success;
}
///
/// Deletes the given file or directory if it exists.
///
/// Path of the file or directory to delete.
public static void DeleteIfExists(string path)
{
if (!File.Exists(path) & !Directory.Exists(path))
{
return;
}
var attributes = File.GetAttributes(path);
// if file is readonly - make it non-readonly
if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
{
File.SetAttributes(path, attributes ^ FileAttributes.ReadOnly);
}
// now delete everything
if (File.Exists(path))
{
File.Delete(path);
}
else if (Directory.Exists(path))
{
foreach (var path2 in Directory.GetDirectories(path).Union(Directory.GetFiles(path)))
{
DeleteIfExists(path2);
}
Directory.Delete(path);
}
}
///
/// Checks if could be a valid file.
///
/// File name to check.
/// True if fileName could be used as a valid file name, false otherwise.
public static bool IsValidFileName(string fileName)
{
return fileName != null
&& fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0
&& fileName.Trim().Length > 0;
}
///
/// Checks if directory is empty.
///
/// The path to the directory.
/// true is directory exists and is empty, false otherwise.
public static bool IsDirectoryEmpty(string path)
{
if (!Directory.Exists(path))
{
return false;
}
return !Directory.EnumerateFileSystemEntries(path).Any();
}
///
/// Computes the checksum for a given file.
///
/// The file path.
/// The checksum.
/// Uses the MD5 checksum algorithm.
public static string GetChecksum(string filePath)
{
using (var md5Algorithm = MD5.Create())
{
using (var stream = File.OpenRead(filePath))
{
var computedByteHash = md5Algorithm.ComputeHash(stream);
return BitConverter.ToString(computedByteHash).Replace("-", "").ToLower();
}
}
}
///
/// Verifies that a given file matches with a checksum.
///
/// The file path.
/// The checksum to be matched.
/// True if the checksum matches; false otherwise.
///
public static bool VerifyChecksum(string filePath, string checksumToBeMatched)
{
var checksum = GetChecksum(filePath);
return Equals(checksumToBeMatched, checksum);
}
///
/// Check if two paths are equal.
/// This prevents failure of forward and backward slashes.
/// It checks on full path names via .
///
public static bool PathsAreEqual(string path1, string path2)
{
var info1 = new FileInfo(path1);
var info2 = new FileInfo(path2);
return info1.FullName == info2.FullName;
}
}
}