我正在学习一个用C#语言编写的库存管理系统的教程。
最初的csv文件是一个股票列表,其中包含四个类别:
Item Code, Item Description, Item Count, OnOrder
原始csv文件:
在教程中,代码正在生成一个DataTable对象,该对象将在应用程序中的GridView演示中使用。
下面是代码:
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Item Code");
dataTable.Columns.Add("Item Description");
dataTable.Columns.Add("Current Count");
dataTable.Columns.Add("On Order");
string CSV_FilePath = "C:/Users/xxxxx/Desktop/stocklist.csv";
StreamReader streamReader = new StreamReader(CSV_FilePath);
string[] rawData = new string[File.ReadAllLines(CSV_FilePath).Length];
rawData = streamReader.ReadLine().Split(',');
while(!streamReader.EndOfStream)
{
rawData = streamReader.ReadLine().Split(',');
dataTable.Rows.Add(rawData[0], rawData[1], rawData[2], rawData[3]);
}
dataGridView1.DataSource = dataTable;
我假设rawdata=StreamReader.ReadLine().split(',');
将文件拆分为如下数组对象:
["A0001", "Horse on Wheels","5","No"]
["A0002","Elephant on Wheels","2","No"]
在while循环中,它通过每一行(每个数组)进行读写,并将每个rawdata[x]分配到相应的列中。
这样理解这个代码片段是正确的吗?提前谢谢你。
另一个问题是,我为什么要跑
rawData = streamReader.ReadLine().Split(',');
在while循环中?
提前谢谢你。
您的代码实际上应该如下所示:
DataTable dataTable = new DataTable();
dataTable.Columns.Add("Item Code");
dataTable.Columns.Add("Item Description");
dataTable.Columns.Add("Current Count");
dataTable.Columns.Add("On Order");
string CSV_FilePath = "C:/Users/xxxxx/Desktop/stocklist.csv";
using(StreamReader streamReader = new StreamReader(CSV_FilePath))
{
// Skip the header row
streamReader.ReadLine();
while(!streamReader.EndOfStream)
{
string[] rawData = streamReader.ReadLine().Split(','); // read a row and split it into cells
dataTable.Rows.Add(rawData[0], rawData[1], rawData[2], rawData[3]); // add the elements from each cell as a row in the datatable
}
}
dataGridView1.DataSource = dataTable;
我所做的更改:
StreamReader
周围添加了一个using块,以确保文件句柄仅在需要读取文件时打开。rawdata
,所以我将它移到循环中。解释问题:
下面一行读取整个文件,然后计算其中有多少行。利用这些信息,我们初始化一个数组,其位置与文件中的行数一样多。这意味着对于500行文件,您可以访问位置RawData[0]
,RawData[1]
,...RawData[499]
。
string[] rawData = new string[File.ReadAllLines(CSV_FilePath).Length];
对于下一行,您将丢弃该数组,取而代之的是文件顶部的单元格(标题):
rawData = streamReader.ReadLine().Split(',');
这一行声明“从文件中读取单行,并按逗号拆分”。然后将该结果分配给rawdata
,替换其旧值。因此,在循环中再次需要该文件的原因是,您感兴趣的不仅仅是文件的第一行。
最后,循环遍历文件中的每一行,并用该行中的单元格替换rawdata
。最后,将每一行添加到DataTable
:
rawData = streamReader.ReadLine().Split(',');
dataTable.Rows.Add(rawData[0], rawData[1], rawData[2], rawData[3]);
请注意,file.ReadAllLines(。。。)
将整个文件作为字符串数组读入内存。您还使用StreamReader
逐行读取文件,这意味着您将两次读取整个文件。这不是非常有效,您应该尽可能避免这种情况。在这种情况下,我们根本不需要这么做。
还要注意,您读取CSV文件的方法相当幼稚。根据创建它们所用的软件,有些CSV文件的单元格跨越文件中的多行,有些包含带引号的文本部分,有时那些带引号的部分包含逗号,这会使您的拆分代码脱节。您的代码也没有处理文件格式错误的可能性,例如一行的单元格比预期的少,或者文件末尾有一个空行。一般来说,最好使用专用的CSV解析器,比如CsvHelper,而不是尝试滚动自己的解析器。