在C#中读取,拆分和显示多行CSV文件 [英] Reading, splitting, and displaying a multiline CSV file in C#

查看:182
本文介绍了在C#中读取,拆分和显示多行CSV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部,



我试图编写一个测试程序,最终允许我取一个CSV .txt文件,并将其内容放入SQLite数据库文件。我正在使用的.txt文件有数百行。



这里是我到目前为止:一个带有三个按钮的WPF表单 -



退出: / p>

加载CSV文件:弹出Win32打开文件对话框。



当前目录信息:查找程序正在操作的当前目录,并显示它。



文本块,显示程序的输出中的各种信息 - 基本上,无论我想要什么,像异常等。



为了读取文本文件,我实现以下代码:

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

命名空间C_Sharp_SQLite_Testbed
{
///< summary>
/// MainWindow.xaml的交互逻辑
///< / summary>
public partial class MainWindow:Window
{

私有静态字符串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 =文本文档(.txt)| * .txt;

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

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

try
{
使用(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_Click StreamReader 方法从对话框中接收 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#从来没有真正是我的forte。



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



时间,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。






编辑:



这是一个新块读取行。到目前为止工作良好,现在,需要将事物拆分为2D数组。

 请尝试
{
使用(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] +\\\

}

}


解决方案

这是我会这样做的:



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

  public 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;组; }
public int HLState {get;组; }
public double HLX {get;组; }
public double HLY {get;组; }
public double HLZ {get;组; }
}

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

  private void btnLoad_Click(object sender,RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft。 Win32.OpenFileDialog();
dlg.FileName =Document;
dlg.DefaultExt =.txt;
dlg.Filter =文本文档(.txt)| * .txt;

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

var output = new List< MyData>();

try
{
//第一行跳过,因为我们不需要标题。
foreach(File.ReadAllLines(filename).Skip(1))中的var行
{
output.Add(new MyData(line.Split(,)));
}

OutputConsole.Text = string.Format({0} lines read。,output.Lenght);
}
catch(System.IO.IOException ex)
{
//让用户知道读取文件时出错
}

//使用输出执行操作

}
}

现在你有一个集合输出的对象,每个对象都具有对你的值的强类型访问,这应该很容易填充到一个数据库


All,

I'm trying to write a testbed program that will eventually allow me to take a CSV .txt file and put its contents into a SQLite database file. There are hundreds of lines to the .txt files I'm working with.

Here's what I have so far: a WPF form with three buttons-

Exit: self-explanatory

Load CSV file: pops up a Win32 Open File dialog box.

Current Directory Info: Finds the current directory the program is operating from, and displays it.

and a Text Block, that displays various information from the program's output- basically, whatever I want it to, things like exceptions, etc.

In order to read the text file, I implement the following code:

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

It's a fairly simple setup, and the only method I'm having problems with is in btnLoad_Click. The StreamReader method receives the fileName variable from the dialog box as an argument. It successfully opens the file. While not at the end of the file stream, a line is read using var line = sr.ReadLine();. We then split the line up into an array using var lineWords = line.Split(',');. Afterwards, the length of the lineWords array is printed to the text block using OutputConsole.Text = Convert.ToString(lienWords.Length);. The problem is this: it would seem as if only one value is being read from the file, the reader stops at the first comma, and then ceases to read. The array value being printed is 1, and only one value is printed when I change OutputConsole.Text = Convert.ToString(lineWords.Length) to OutputConsole.Text = Convert.ToString(lineWords[1]);. Furthermore, it's not the correct value. So basically, I only have one space in the array, and it's not filled with the right value.

What do you guys suggest to change this? File reading in C# has never really been my forte.

EDIT: Here are the first two lines, as a sampler of what is in the file. It's Kinect output.

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

Those are just headers.

Second line: 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

I believe the encoding is ANSI.


EDIT:

Here's the "new" block for the reading of lines. Works good so far, now, there's a need to split up things into a 2D array.

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";
    }

}

解决方案

This is how I would do it:

First, define a class to hold the output of your file:

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

Then modify you button event to populate a list of those objects

    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

        }
    }

Now you have a collection output of objects each with a strong typed access to your values, which should easily populate into a DB

这篇关于在C#中读取,拆分和显示多行CSV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆