/// <summary> /// Most files are organized as a table where lines are rows and columns are separated by a delimiter. This allows /// easy processing of such files, along with line trimming, removing empty lines, etc. /// </summary> /// <param name="filePath"></param> /// <param name="settings"></param> /// <returns>Outer list is the rows, inner lists are the columns</returns> public static List <List <string> > SplitDelimitedFileByLines(string filePath, SplitFileSettings settings) { List <string> lines = new List <string>(); ThreadingServices.WaitOnAction(() => lines = File.ReadAllLines(filePath).ToList(), settings.FileReadTimeout); List <List <string> > results = new List <List <string> >(); foreach (var line in lines) { var entries = line.Split(settings.Delimiters).ToList(); if (settings.TrimEntries) { entries = entries.Select(x => x.Trim()).ToList(); } if (settings.RemoveEmptyEntries) { entries = entries.Where(x => !string.IsNullOrEmpty(x)).ToList(); } if (settings.RemoveEmptyLines & entries.Count < 1) { continue; } results.Add(entries); } return(results); }
/// <summary> /// Force a file to be copied, even if the destination exists and is read-only. Retries for the specified /// timeout period (default 3 seconds) if it fails /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// <param name="timeout"></param> public static void ForceCopy(string source, string destination, TimeSpan?timeout = null) { if (timeout == null) { timeout = TimeSpan.FromSeconds(3); } TimeSpan realTimeout = (TimeSpan)timeout; if (File.Exists(destination)) { ForceDelete(destination, realTimeout); } ThreadingServices.WaitOnAction(() => File.Copy(source, destination, true), realTimeout); }
/// <summary> /// Force a file to be deleted, even if it is read-only. Retries for the specified timeout period /// (default 3 seconds) if it fails. /// </summary> /// <param name="filename"></param> /// <param name="timeout"></param> public static void ForceDelete(string filename, TimeSpan?timeout = null) { if (timeout == null) { timeout = TimeSpan.FromSeconds(3); } TimeSpan realTimeout = (TimeSpan)timeout; ThreadingServices.WaitOnAction(() => File.SetAttributes(filename, FileAttributes.Normal), realTimeout); ThreadingServices.WaitOnAction(() => File.Delete(filename), realTimeout); ThreadingServices.WaitOnAction(() => { if (File.Exists(filename)) { throw new Exception("File still exists"); } }, realTimeout); }
/// <summary> /// Force a directory to be deleted, even if it contains read-only files. Retries for the specified /// timeout period (default 3 seconds) if it fails. /// </summary> /// <remarks>This method forces every file to have normal file permissions, and DOES NOT /// put the permissions back to normal if it fails. If this is unnacceptable, you may want to /// write a custom method using FileServices.ForceDelete</remarks> /// <param name="directoryPath"></param> /// <param name="timeout"></param> public static void ForceDelete(string directoryPath, TimeSpan?timeout = null) { if (timeout == null) { timeout = TimeSpan.FromSeconds(3); } TimeSpan realTimeout = (TimeSpan)timeout; DateTime start = DateTime.Now; foreach (var filename in Directory.EnumerateFiles(directoryPath, "*", SearchOption.AllDirectories)) { if (File.GetAttributes(filename) != FileAttributes.Normal) { ThreadingServices.WaitOnAction(() => File.SetAttributes(filename, FileAttributes.Normal), realTimeout - (DateTime.Now - start)); } } ThreadingServices.WaitOnAction(() => Directory.Delete(directoryPath, true), realTimeout - (DateTime.Now - start)); ThreadingServices.WaitOnAction(() => { if (Directory.Exists(directoryPath)) { throw new Exception("Directory still exists"); } }, realTimeout - (DateTime.Now - start)); }