/// <summary> /// Returns the encoding of the input file /// </summary> /// <param name="srcFile"></param> /// <returns></returns> public static Encoding GetFileEncoding(string srcFile) { var encoding = Encoding.Default; if (string.IsNullOrEmpty(srcFile) || !File.Exists(srcFile)) { return(encoding); } // Read in the file in binary byte[] buffer; try { using (var file = new FileStream(srcFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var memoryStream = new MemoryStream()) { file.CopyTo(memoryStream); buffer = memoryStream.ToArray(); } } } catch (Exception) { return(encoding); } // Detect encoding var textDetect = new TextEncodingDetect(); var textEnc = textDetect.DetectEncoding(buffer, buffer.Length); switch (textEnc) { case EncodingEnum.Ascii: // ASCII (chars in the 0-127 range) encoding = Encoding.ASCII; break; case EncodingEnum.Ansi: // ANSI (chars in the range 0-255 range) encoding = Encoding.Default; break; case EncodingEnum.Utf8Bom: case EncodingEnum.Utf8Nobom: // UTF-8 encoding = Encoding.UTF8; break; case EncodingEnum.Utf16LeBom: case EncodingEnum.Utf16LeNobom: // UTF-16 Little Endian encoding = Encoding.Unicode; break; case EncodingEnum.Utf16BeBom: case EncodingEnum.Utf16BeNobom: // UTF-16 Big Endian encoding = Encoding.BigEndianUnicode; break; } return(encoding); }
/// <summary> /// Read all the text of a file in one go, same as File.ReadAllText expect it's truly a read only function /// </summary> public static string ReadAllText(string path, Encoding encoding = null) { try { using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (var textReader = new StreamReader(fileStream, encoding ?? TextEncodingDetect.GetFileEncoding(path))) { return(textReader.ReadToEnd()); } } } catch (Exception e) { throw new Exception($"Can not read the file {path.PrettyQuote()}.", e); } }
/// <summary> /// Reads all the line of either the filePath (if the file exists) or from byte array dataResources, /// Apply the action toApplyOnEachLine to each line /// Uses encoding as the Encoding to read the file or convert the byte array to a string /// Uses the char # as a comment in the file /// </summary> public static bool ForEachLine(string filePath, byte[] dataResources, Action <int, string> toApplyOnEachLine, Encoding encoding = null, Action <Exception> onException = null) { encoding = encoding ?? TextEncodingDetect.GetFileEncoding(filePath); var wentOk = true; try { SubForEachLine(filePath, dataResources, toApplyOnEachLine, encoding); } catch (Exception e) { wentOk = false; onException?.Invoke(e); // read default file, if it fails then we can't do much but to throw an exception anyway... if (dataResources != null) { SubForEachLine(null, dataResources, toApplyOnEachLine, encoding); } } return(wentOk); }