如何使用C#验证CSV文件从文件列表到其相应类别?
我的目录中有多个CSV文件,属于三个不同的类别(文件A、文件B和文件C),具有不同的列结构/数据。我正在使用SmartXLS库编写一个控制台应用程序,它读取一个新文件(比如文件Z),并告诉我它属于哪个类别(a/B/C) 我能够从目录中读取多个文件,但无法编写验证文件的逻辑。请帮我做这个 文件格式: 文件A:使用日期、产品名称、用户Id、使用的令牌。 文件B:原因、月份、调整日期、交易ID、调整的代币,如何使用C#验证CSV文件从文件列表到其相应类别?,c#,C#,我的目录中有多个CSV文件,属于三个不同的类别(文件A、文件B和文件C),具有不同的列结构/数据。我正在使用SmartXLS库编写一个控制台应用程序,它读取一个新文件(比如文件Z),并告诉我它属于哪个类别(a/B/C) 我能够从目录中读取多个文件,但无法编写验证文件的逻辑。请帮我做这个 文件格式: 文件A:使用日期、产品名称、用户Id、使用的令牌。 文件B:原因、月份、调整日期、交易ID、调整的代币, 产品名称,添加评论。 文件C:使用日期、产品名称、产品版本、用户Id、机器名称、, 服务器名称
产品名称,添加评论。 文件C:使用日期、产品名称、产品版本、用户Id、机器名称、, 服务器名称、使用的令牌、使用的小时数 功能:
public void ValidateData()
{
int count = 0;
Tokens = new List<Token>();
var files = Directory.EnumerateFiles(@"C:\Projects", "*.csv");
foreach (string file in files)
{
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
SmartXLS.WorkBook WB = new WorkBook();
WB.readCSV(file);
DataTable dt = WB.ExportDataTable();
string dtSTR;
DataRow dr;
for (int i = 1; i < dt.Rows.Count; i++)
{
dr = dt.Rows[i];
try
{
dtSTR = dr[0].ToString();
if (string.IsNullOrEmpty(dtSTR)) continue;
var tkn = new Token();
tkn.Usagedate = ParseDateTime(dtSTR);
tkn.Product_name = dr[1].ToString();
tkn.Product_Version = dr[2].ToString();
tkn.Userid = dr[3].ToString();
Tokens.Add(tkn);
count++;
Console.WriteLine("Read : " + count);
Console.WriteLine(" Reading : " + tkn.Usagedate + "," + tkn.Product_name + "," + tkn.Product_Version + "," + tkn.Userid);
}
catch (Exception ex)
{
}
}
}
}
}
public void ValidateData()
{
整数计数=0;
令牌=新列表();
var files=Directory.EnumerateFiles(@“C:\Projects”,“*.csv”);
foreach(文件中的字符串文件)
{
使用(FileStream fs=newfilestream(file,FileMode.Open,FileAccess.Read))
{
SmartXLS.WorkBook WB=新工作簿();
WB.readCSV(文件);
DataTable dt=WB.ExportDataTable();
字符串dtSTR;
数据行dr;
对于(int i=1;i
如果这些是简单的.csv文件,您只需要对它们进行分类,那么您可以使用块跳过中的几乎所有逻辑,将文件视为简单文本,这可能会更有效
你没有提到格式上的差异,所以我只能猜测。每个类别是否有不同数量的列?如果是这样,您可以选择一行,使用String.Split
创建一个字符串数组(每列一个字符串),然后使用数组的长度确定有多少列。它看起来像这样:
public void ValidateData()
{
var files = Directory.EnumerateFiles(@"C:\Projects", "*.csv");
foreach (string file in files)
{
// get a string array with one string per row
string[] fileRows = File.ReadAllLines(file);
foreach (string row in fileRows)
{
// ignore blank lines
if (row.Trim() != "")
{
char[] splitOn = new char[] {','}; // if the csv files use comma as a delimiter
string[] columns = row.Split(splitOn); // this splits the row into one string per column
int numberOfCols = columns.Length; // this is how many columns you have
// use this info to determine the type of file.
if (numberOfCols == 4)
{
Debug.WriteLine("This is category A");
}
else if (numberOfCols == 5)
{
Debug.WriteLine("This is category B");
}
else if (numberOfCols == 7)
{
Debug.WriteLine("This is category C");
}
else
{
Debug.WriteLine("Unexpected file type.");
}
break; // end the loop now - we've already done what we needed to do.
}
}
}
}
如果它们具有相同的列数,但第一列中的信息不同,那么您可以更改If语句以检查有关列[0]的信息,这将为您提供有关它是哪种类型的线索。。。例如,您说文件A的第一列中有一个日期,因此您可以使用DateTime.TryParse(列[0],out-var-date)
在第一列包含日期时返回true,在第一列不包含日期时返回false。如果您更具体地了解文件类型之间的差异,那么就更容易提供具体的帮助
编辑:在上面的示例中,变量行
表示非空的第一行数据。如果CSV文件的第一行包含列标题,则只需检查字符串即可查看列标题:
public void ValidateData()
{
var files = Directory.EnumerateFiles(@"C:\Projects", "*.csv");
foreach (string file in files)
{
// get a string array with one string per row
string[] fileRows = File.ReadAllLines(file);
foreach (string row in fileRows)
{
// ignore blank lines
if (row.Trim() != "")
{
char[] splitOn = new char[] { ',' }; // if the csv files use comma as a delimiter
string[] columns = row.Split(splitOn); // this splits the row into one string per column
// the third column (columns[2]) is the first that is different for all file types.
if (columns[2] == "User ID")
{
Debug.WriteLine("This is file A");
}
else if (columns[2] == "Adjustment Date")
{
Debug.WriteLine("This is file B");
}
else if (columns[2] == "Product Version")
{
Debug.WriteLine("This is file C");
}
else
{
Debug.WriteLine("Unknown file type.");
}
break; // end the loop now - we've already done what we needed to do.
}
}
}
}
具有不同的列结构/数据。这些不同的结构是什么?我试着附加图片,但出于某种原因,它不允许我。以下是结构:文件A:使用日期、产品名称、用户Id、使用的令牌文件B:原因、月份、调整日期、事务Id、调整的令牌、产品名称、添加的注释文件C:使用日期、产品名称、产品版本、用户Id、机名、服务器名称、使用的令牌、使用的小时数。以上是三个文件@SachPlease的单独列标题,请使用此信息更新您的原始帖子。我本打算在OP更新了差异信息后发布答案,但您抢先一步。差不多就是这样+1没有简洁的代码。谢谢。是的,我在他发布细节之前就开始了,但这应该会让OP非常接近基于他的澄清的解决方案。谢谢@ElementalPete。您能建议我一种使用列名而不是列计数(列数)来验证数据的方法吗?因为将来列计数可能会更改。@Rck7-请参阅更新的答案。这假设列名实际出现在电子表格的第1行。。。在不了解您的项目的更多信息的情况下,这可能不是一个安全的假设。@ElementalPete-我已经尝试了您更新的答案,但出于某种原因,它将进入else循环,打印“未知文件类型”(尽管我给出了正确的列名)。关于该项目的一些信息:我下载了三个类别的多个CSV文件中产品的每日令牌使用数据。因此,我正在尝试编写一个控制台应用程序,将所有这些文件读写到数据库中的一个表中,这样我就可以自动完成所有类型的计算(总和/每月/每年等)。你能建议我用字典吗?使用colname、conindex作为对?