2013-05-30 63 views
4

所有,阅读,分裂,并显示在C#中的多CSV文件

我试图写一个测试平台计划,将最终允许我采取CSV txt文件,并把它的内容到SQLite数据库文件。有数百行我正在使用的.txt文件。

这是我到目前为止有:一个WPF形式有三个buttons-

退出:不言自明

负载CSV文件:弹出一个Win32打开文件对话框。

当前目录信息:查找程序运行的当前目录并显示它。

和文本块,基本上显示从程序的输出 - 各种信息,无论我想它,像异常等

为了阅读文本文件,我执行下面的代码:

using System; 
using System.Data; 
using System.Data.SQLite; 
using System.IO; 
using System.Windows; 
using System.Windows.Controls; 

namespace C_Sharp_SQLite_Testbed 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

     private static string fileName; 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void btnLoad_Click(object sender, RoutedEventArgs e) 
     { 
      Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 
      dlg.FileName = "Document"; 
      dlg.DefaultExt = ".txt"; 
      dlg.Filter = "Text Documents (.txt)|*.txt"; 

      Nullable<bool> result = dlg.ShowDialog(); 

      if (result == true) 
      { 
       fileName = dlg.FileName; 
       OutputConsole.Text = " "; 
       OutputConsole.Text = fileName; 

       try 
       { 
        using (StreamReader sr = new StreamReader(fileName)) 
        { 
         while (!sr.EndOfStream) 
         { 
          var line = sr.ReadLine(); 
          var lineWords = line.Split(','); 
          OutputConsole.Text = Convert.ToString(lineWords.Length); 

         } 
        } 
       } 
       catch (Exception ex) 
       { 
        OutputConsole.Text = " "; 
        OutputConsole.Text = ex.Message; 
       } 
      } 
     } 

     private void btnExit_Click(object sender, RoutedEventArgs e) 
     { 
      Environment.Exit(0); 
     } 

     private void btnInfo_Click(object sender, RoutedEventArgs e) 
     { 
      Environment.CurrentDirectory = Environment.GetEnvironmentVariable("windir"); 
      DirectoryInfo info = new DirectoryInfo("."); 
      lock (info) 
      { 
       OutputConsole.Text = String.Format("Directory info: " + info.FullName); 
      } 
     } 
    } 
} 

这是一个相当简单的设置,和我有问题的唯一方法是在btnLoad_ClickStreamReader方法接收对话框中的fileName变量作为参数。它成功打开文件。虽然不在文件流的末尾,但是使用var line = sr.ReadLine();来读取一行。然后我们使用var lineWords = line.Split(',');将该行分成一个数组。之后,使用OutputConsole.Text = Convert.ToString(lienWords.Length);将lineWords数组的长度打印到文本块。问题是这样的:看起来好像只有一个值正在从文件中读取,读者停在第一个逗号,然后停止阅读。正在打印的数组值为1,当我将OutputConsole.Text = Convert.ToString(lineWords.Length)更改为OutputConsole.Text = Convert.ToString(lineWords[1]);时,只打印一个值。此外,这不是正确的价值。所以基本上,我只在数组中有一个空格,并且没有填充正确的值。

你们建议如何改变这种情况?在C#中阅读文件从来都不是我的特长。

编辑:这是前两行,作为文件中的内容的取样器。这是Kinect输出。

Time,HLState,HLX,HLY,HLZ,KLState,KLX,KLY,KLZ,ALState,ALX,ALY,ALZ,FLState,FLX,FLY,FLZ,HRState,HRX,HRY,HRZ,KRState,KRX,KRY,KRZ,ARState,ARX,ARY,ARZ,FRState,FRX,FRY,FRZ,lknfx,lknvg,rknfx,rknvg

这些只是头。

下联: 700449555,2,-0.2912986,-0.1036692,1.472573,2,-0.2512482,-0.472762,1.416523,1,-0.2034467,-0.9132867,1.340637,1,-0.1271965,-0.9447169,1.280763,2,-0.197726,-0.09682589,1.596856,2,-0.1457276,-0.5412285,1.782268,2,-0.184881,-0.5280698,1.408923,2,-0.1630141,-0.537811,1.523656,178.867138094441,12.3859203137083,64.9231529324685,142.847159325228

我相信编码是ANSI。


编辑:

下面是行的阅读 “新” 块。目前为止工作良好,现在需要将事物分解成二维数组。

try 
{ 
    using (StreamReader sr = new StreamReader(fileName)) 
    { 
     lines = File.ReadAllLines(fileName);       
    } 

    int numberLines = lines.Length; 
    OutputConsole.Text = " "; 
    OutputConsole.Text += numberLines + " "; 
    for (int i = 0; i < numberLines; i++) 
    { 
     OutputConsole.Text += lines[i] + "\n"; 
    } 

} 
+2

为什么不只是'string [] lines = File.ReadAllLines(fileName)' –

+0

或者'string text = File.ReadAllText(fileName)' –

+0

请让我们把你的文件(或其中的一部分)和它的内容编码。 –

回答

2

这是我会怎么做:

首先,定义一个类来保存你的文件的输出:

public class MyData 
{ 
    public MyData() { } 

    public MyData(string[] values) 
    { 
     Time = new DateTime(long.Parse(values[0])); 
     HlState = int.Parse(values[1]); 
     HLX = double.Parse(values[2]); 
     HLY = double.Parse(values[3]); 
     HLZ = double.Parse(values[4]); 
    } 

    public DateTime Time { get; set; } 
    public int HLState { get; set; } 
    public double HLX { get; set; } 
    public double HLY { get; set; } 
    public double HLZ { get; set; } 
} 

然后修改你的按钮事件来填充这些对象的列表

private void btnLoad_Click(object sender, RoutedEventArgs e) 
    { 
     Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); 
     dlg.FileName = "Document"; 
     dlg.DefaultExt = ".txt"; 
     dlg.Filter = "Text Documents (.txt)|*.txt"; 

     if (dlg.ShowDialog() == true) 
     { 
      fileName = dlg.FileName; 
      OutputConsole.Text = " "; 
      OutputConsole.Text = fileName; 

      var output = new List<MyData>(); 

      try 
      { 
       // First line skipped as we do not need headers. 
       foreach (var line in File.ReadAllLines(filename).Skip(1)) 
       { 
        output.Add(new MyData(line.Split(","))); 
       } 

       OutputConsole.Text = string.Format("{0} lines read.", output.Lenght); 
      } 
      catch (System.IO.IOException ex) 
      { 
       //let user know there was an error reading file 
      } 

      // Do something with output 

     } 
    } 

现在你有一个对象集合output,每个对象都具有对你的值的强类型访问,这应该很容易地填充到一个DB中

+0

我应该有多少个“值”字段的实例? – nerdenator

+0

是的,抱歉,那不清楚。 MyData类应该对每个CSV的“列”都有一个属性,并进行适当的命名和输入。也可以随意将“MyData”重命名为更适用于您正在做的事情。 – Jay

+0

我会尝试并执行此操作。会回到你身边。 – nerdenator

2

您的文件读取代码有点奇怪(它有一些小的减少)但我不认为这是问题。通常(遵循msdn示例)while循环是这样写的;

string line; 
    while ((line = sr.ReadLine()) != null) { ... } 

此外作为评论建议你可以使用string[] lines = File.ReadAllLines(fileName);然后遍历所有的线,中间的分割逻辑。我建议从您的代码中移除EndOfStream并使用其他两种方法之一。我不知道它会解决你的问题,但是这突出表现为不完全正常的事情。

此外,您的输出不好,因为您没有追加到文本框,您正在设置它的值。这意味着你只会看到文件中最后一行的长度。如果你想看到每行的长度,它需要是OutputConsole.Text += lineWords.Length + " ";如果你不知道有一个隐式转换完成,所以不需要显式转换,这只会使代码变得不可读。