我正在创建一个应用程序,它将MS Access表和Excel表转换为.csv文件,然后将访问表与excel表区分开来。 .csv文件很好但是生成的差异文件在包含html的字段中有错误(访问表包含带有html的字段)。我不确定这是否是一个特殊的字符问题,因为特殊字符在创建.csv文件时不是问题,或者如果我对差异这两个文件的方式存在问题。
我认为部分问题可能是在访问.csv文件中,包含html的字段被格式化,以便某些信息在单独的行上而不是在一行上的所有信息,这可能会丢掉读者,但我不知道如何纠正这个问题。
这是用于创建差异文件的代码:
string destination = Form2.destination;
string path = Path.Combine(destination, "en-US-diff.csv");
string difFile = path;
if (File.Exists(difFile))
{
File.Delete(difFile);
}
using (var wtr = new StreamWriter(difFile))
{
// Create the IEnumerable data sources
string[] access = System.IO.File.ReadAllLines(csvOutputFile);
string[] excel = System.IO.File.ReadAllLines(csvOutputFile2);
// Create the query
IEnumerable<string> differenceQuery = access.Except(excel);
// Execute the query
foreach (string s in differenceQuery)
{
wtr.WriteLine(s);
}
}
答案 0 :(得分:1)
物理线与逻辑线。一种解决方案是使用一个sentinel,它只是一个以这种方式选择的任意字符串标记,以免混淆解析过程,例如“## || ##”。
创建输入文件后,将标记添加到每行的末尾...
1,1,1,1,1,1,### || ##
回到你的代码,System.IO.File.ReadAllLines(csvOutputFile);使用Environment.Newline字符串作为其sentinel。这意味着您需要将此语句替换为以下(伪代码)...
const string sentinel = "##||##";
string myString = File.ReadAllText("myFileName.csv");
string[] access = myString.Split(new string[]{sentinel},
StringSplitOptions.RemoveEmptyEntries);
此时,您将在“访问”数组中以您想要的方式将CSV行作为“逻辑”行的集合。
为了使事情更符合要求,您还需要在数组的每一行上执行此语句...
line = line.Replace(Environment.NewLine, String.Empty).Trim();
这将删除罪魁祸首,并允许您使用已经开发的方法解析CSV。当然,如果需要,可以将此语句与LINQ表达式中的IO语句结合使用。