C# Processing Fixed Width Files

匿名 (未验证) 提交于 2019-12-03 02:03:01

问题:

I have a collection of fixed width files with a varying number of columns and field sizes.

The top of the file starts with a line like:

AAAAABBCCCCCCCCCCDDD and so on

The change in character denotes the end of one field and the start of another. I am guessing this can someone be used to work out what the field sizes are with code and then apply the same values to the actual data lines below.

I then want to output all the read data into a XLS file or even a DataGrid, but my issue is I have no idea how to code this.

Any help would be greatly appreciated :)


/Edit:

I implemented Cuong's solution and although that worked fine for testing on my home PC, I had to compile it with c# v4 as our work PCs have Windows XP.

Anyways, when reading the input file I get the following error:

************** Exception Text ************** System.ObjectDisposedException: Cannot read from a closed TextReader.    at System.IO.__Error.ReaderClosed()    at System.IO.StreamReader.ReadLine()    at System.IO.File.d__0.MoveNext()    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()    at System.IO.File.InternalWriteAllLines(TextWriter writer, IEnumerable`1 contents)    at System.IO.File.WriteAllLines(String path, IEnumerable`1 contents)    at FixedWidthFiles.Main.buttonProcessFile_Click(Object sender, EventArgs e)    at System.Windows.Forms.Control.OnClick(EventArgs e)    at System.Windows.Forms.Button.OnClick(EventArgs e)    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)    at System.Windows.Forms.Control.WndProc(Message& m)    at System.Windows.Forms.ButtonBase.WndProc(Message& m)    at System.Windows.Forms.Button.WndProc(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)   ************** Loaded Assemblies ************** mscorlib     Assembly Version: 4.0.0.0     Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)     CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll ---------------------------------------- FixedWidthFiles     Assembly Version: 1.0.0.0     Win32 Version: 1.0.0.0     CodeBase: file:///C:/TEMP/FixedWidthFiles.exe ---------------------------------------- System.Windows.Forms     Assembly Version: 4.0.0.0     Win32 Version: 4.0.30319.1 built by: RTMRel     CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll ---------------------------------------- System.Drawing     Assembly Version: 4.0.0.0     Win32 Version: 4.0.30319.1 built by: RTMRel     CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll ---------------------------------------- System     Assembly Version: 4.0.0.0     Win32 Version: 4.0.30319.1 built by: RTMRel     CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll ---------------------------------------- System.Core     Assembly Version: 4.0.0.0     Win32 Version: 4.0.30319.1 built by: RTMRel     CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll ---------------------------------------- 

回答1:

Below example how to write in csv file (excel type), the main point is you need to read the first line and calculate width:

var lines = File.ReadLines("C:\\input.txt");  var widthList = lines.First().GroupBy(c => c)                              .Select(g => g.Count())                              .ToList();  var list = new List>();  int startIndex = 0;  for (int i = 0; i (startIndex, widthList[i]);     list.Add(pair);      startIndex += widthList[i]; }  var csvLines = lines.Select(line => string.Join(",",                      list.Select(pair => line.Substring(pair.Key, pair.Value))));  File.WriteAllLines("C:\\test.csv", csvLines); 


回答2:

You can use TextReader.Read method. For example:

    string input; // Test string      // Replace new StringReader with a StreamReader to read a file     using (TextReader textReader = new StringReader(input))     {         // Read first line to get structure         var groupings = textReader.ReadLine().GroupBy(x => x);          while (textReader.Peek() != -1)         {             // Convert to a string for easier handling than char[]             List fields = new List();              // Get the fields on each ling             foreach (IGrouping grouping in groupings)             {                 char[] field = new char[grouping.Count()];                 textReader.Read(field, 0, field.Length);                 fields.Add(new string(field));             }              // Do something with "fields". The name of each field is             // in grouping.Key at the same index.              // Move to next line             textReader.ReadLine();         }     } 


回答3:

Use the class TextFieldParser type per this how-to for Visual Basic.

You'll need to tell it the widths of the fields. Given your first line, that's easy enough.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!