C#处理固定宽度文件

我有一组固定宽度的文件,具有不同数量的列和字段大小。

文件顶部以如下行开头:

AAAAABBCCCCCCCCCCDDD等

字符的变化表示一个字段的结束和另一个字段的开始。 我猜这可以用某人来计算字段大小与代码的关系,然后将相同的值应用于下面的实际数据行。

然后我想将所有读取的数据输出到XLS文件甚至是DataGrid,但我的问题是我不知道如何编写这个。

任何帮助将不胜感激 :)


/编辑:

我实现了Cuong的解决方案,尽管在我的家用PC上进行测试工作正常,但由于我们的工作PC有Windows XP,我不得不用c#v4编译它。

无论如何,当读取输入文件时,我收到以下错误:

************** 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 ---------------------------------------- 

下面的例子如何写入csv文件(excel类型),主要的一点是你需要读取第一行并计算宽度:

 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 < widthList.Count(); i++) { var pair = new KeyValuePair(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); 

您可以使用TextReader.Read方法。 例如:

  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(); } } 

对于Visual Basic,请按照此方法使用类TextFieldParser类型。

你需要告诉它字段的宽度。 鉴于你的第一线,这很容易。