/// <summary> /// Create a fixed-length data file using the provided data table /// </summary> /// <param name="dt"></param> /// <param name="options"></param> /// <param name="filename"></param> public void Write(DataTable dt, FixedLengthImportOptions options, string filename) { #region Sanity Checks if (dt == null) { throw new ArgumentNullException("dt"); } if (string.IsNullOrEmpty(filename)) { throw new ArgumentNullException("filename"); } #endregion //ResizeTableMaxLength(dt); var buffer = new byte[options.RecordLength]; using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read)) using (var w = new BinaryWriter(fs)) { foreach (DataRow dr in dt.Rows) { #region initialize the buffer with spaces for (int i = 0; i < buffer.Length; i++) { buffer[i] = 32; } #endregion foreach (DataColumn dc in dt.Columns) { int start = options.Definition[dc.ColumnName].Start - 1; int len = options.Definition[dc.ColumnName].Length; var value = Encoding.ASCII.GetBytes((dr[dc] ?? string.Empty).ToString()); Array.Copy(value, 0, buffer, start, len); } w.Write(buffer); if (!string.IsNullOrEmpty(options.NewlineChar)) { w.Write(options.NewlineChar); // ends the row with the specified newline delimiter } } w.Flush(); w.Close(); } }
/// <summary> /// Read the filename and return a DataTable /// </summary> /// <param name="filename"></param> /// <param name="options"></param> /// <returns></returns> public DataTable Read(string filename, FixedLengthImportOptions options) { #region Sanity Checks if (!File.Exists(filename)) { throw new FileNotFoundException("File not found: " + filename); } if (options == null) { throw new ArgumentNullException("options"); } if (options.Definition == null) { throw new ArgumentNullException("options.Definition"); } if (options.Definition.Count == 0) { throw new ArgumentException("The list of field spec is empty"); } if (options.Definition.RecordLength <= 0) { throw new ArgumentException("The record length must be greater than zero"); } #endregion var def = options.Definition; int reclen = def.RecordLength; var fi = new FileInfo(filename); // make sure that file size is evenly divisible by the record length. // If not, we will assume that the definition is not valid for this file. if (fi.Length % reclen != 0) { throw new ArgumentException("File size does not break evenly by record length of " + reclen); } var dt = new DataTable(); dt.TableName = Path.GetFileNameWithoutExtension(filename); #region Generate Data Columns foreach (var item in def) { DataColumn dc = new DataColumn(item.Name); dc.DataType = item.Type; if (item.Type == typeof(string)) { dc.MaxLength = item.Length; } dt.Columns.Add(dc); } #endregion #region Populate Data Rows int rownum = 0; foreach (var buffer in FileUtil.ReadFile(filename, reclen, 0)) { if (buffer.Length == 0) { continue; } rownum++; var dr = dt.NewRow(); #region Convert data to column foreach (var item in def) { string val; #if SUPPORT_ENHANCE_FEATURES if (item.Compute) { switch (item.Value.ToString().ToUpper()) { case "COUNTER": val = rownum.ToString(); break; case "DATE": val = DateTime.Now.ToShortDateString(); break; case "TIME": val = DateTime.Now.ToShortTimeString(); break; case "DATETIME": val = DateTime.Now.ToString("s"); break; default: throw new ArgumentException("unknown auto-compute key value = " + item.Value); } } else { if (item.Start == -1) { val = StringUtil.Unescape(item.Value.ToString()); } else #else { #endif { val = ASCIIEncoding.ASCII.GetString(buffer, item.Start - 1, item.Length).Trim(); } } if (string.IsNullOrEmpty(val)) { continue; } object value = DataConvert.ChangeType(val, null, item.Type); if (value == null) { throw new ArgumentException(string.Format("Converting '{0}' to {1} failed: ", val, item.Type.FullName)); } dr[item.Name] = value; } #endregion dt.Rows.Add(dr); } #endregion return(dt); }