CsvHelper:如何从给定的 csv 文件中检测定界符
CsvHelper : How to detect the Delimiter from the given csv file
我正在使用 CsvHelper read/writer 将数据导入 Csv 文件。现在我想解析 csv 文件的分隔符。请问我怎样才能得到这个?
我的代码:
var parser = new CsvParser(txtReader);
delimiter = parser.Configuration.Delimiter;
我总是得到分隔符是“,”,但实际上在 csv 文件中分隔符是“\t”。
我在这个site
中找到了这段代码
public static char Detect(TextReader reader, int rowCount, IList<char> separators)
{
IList<int> separatorsCount = new int[separators.Count];
int character;
int row = 0;
bool quoted = false;
bool firstChar = true;
while (row < rowCount)
{
character = reader.Read();
switch (character)
{
case '"':
if (quoted)
{
if (reader.Peek() != '"') // Value is quoted and
// current character is " and next character is not ".
quoted = false;
else
reader.Read(); // Value is quoted and current and
// next characters are "" - read (skip) peeked qoute.
}
else
{
if (firstChar) // Set value as quoted only if this quote is the
// first char in the value.
quoted = true;
}
break;
case '\n':
if (!quoted)
{
++row;
firstChar = true;
continue;
}
break;
case -1:
row = rowCount;
break;
default:
if (!quoted)
{
int index = separators.IndexOf((char)character);
if (index != -1)
{
++separatorsCount[index];
firstChar = true;
continue;
}
}
break;
}
if (firstChar)
firstChar = false;
}
int maxCount = separatorsCount.Max();
return maxCount == 0 ? '[=10=]' : separators[separatorsCount.IndexOf(maxCount)];
}
separators
是您可以使用的分隔符。
希望有所帮助:)
CSV 是 Comma
分隔值。我认为您无法可靠地检测到是否使用了不同的字符作为分隔符。如果有 header 行,那么您也许可以指望它。
您应该知道使用的分隔符。打开文件时您应该能够看到它。如果文件来源每次都给你一个不同的分隔符并且不可靠,那么我很抱歉。 ;)
如果您只想使用不同的分隔符进行解析,那么您可以设置csv.Configuration.Delimiter
。 http://joshclose.github.io/CsvHelper/#configuration-delimiter
由于我不得不处理 CSV 文件(保存在 MS Excel 中)可能包含不同分隔符的可能性,具体取决于用户的本地化设置,我最终采用了以下方法:
public static string DetectDelimiter(StreamReader reader)
{
// assume one of following delimiters
var possibleDelimiters = new List<string> {",",";","\t","|"};
var headerLine = reader.ReadLine();
// reset the reader to initial position for outside reuse
// Eg. Csv helper won't find header line, because it has been read in the Reader
reader.BaseStream.Position = 0;
reader.DiscardBufferedData();
foreach (var possibleDelimiter in possibleDelimiters)
{
if (headerLine.Contains(possibleDelimiter))
{
return possibleDelimiter;
}
}
return possibleDelimiters[0];
}
我还需要重置 reader 的读取位置,因为它与我在 CsvReader 构造函数中使用的实例相同。
当时的用法如下:
using (var textReader = new StreamReader(memoryStream))
{
var delimiter = DetectDelimiter(textReader);
using (var csv = new CsvReader(textReader))
{
csv.Configuration.Delimiter = delimiter;
... rest of the csv reader process
}
}
有(至少现在)一个设置为 false 的 DetectDelimiter 值。
然后你可以添加你想测试的愿望分隔符,尽管默认是合理的
我正在使用 CsvHelper read/writer 将数据导入 Csv 文件。现在我想解析 csv 文件的分隔符。请问我怎样才能得到这个?
我的代码:
var parser = new CsvParser(txtReader);
delimiter = parser.Configuration.Delimiter;
我总是得到分隔符是“,”,但实际上在 csv 文件中分隔符是“\t”。
我在这个site
中找到了这段代码public static char Detect(TextReader reader, int rowCount, IList<char> separators)
{
IList<int> separatorsCount = new int[separators.Count];
int character;
int row = 0;
bool quoted = false;
bool firstChar = true;
while (row < rowCount)
{
character = reader.Read();
switch (character)
{
case '"':
if (quoted)
{
if (reader.Peek() != '"') // Value is quoted and
// current character is " and next character is not ".
quoted = false;
else
reader.Read(); // Value is quoted and current and
// next characters are "" - read (skip) peeked qoute.
}
else
{
if (firstChar) // Set value as quoted only if this quote is the
// first char in the value.
quoted = true;
}
break;
case '\n':
if (!quoted)
{
++row;
firstChar = true;
continue;
}
break;
case -1:
row = rowCount;
break;
default:
if (!quoted)
{
int index = separators.IndexOf((char)character);
if (index != -1)
{
++separatorsCount[index];
firstChar = true;
continue;
}
}
break;
}
if (firstChar)
firstChar = false;
}
int maxCount = separatorsCount.Max();
return maxCount == 0 ? '[=10=]' : separators[separatorsCount.IndexOf(maxCount)];
}
separators
是您可以使用的分隔符。
希望有所帮助:)
CSV 是 Comma
分隔值。我认为您无法可靠地检测到是否使用了不同的字符作为分隔符。如果有 header 行,那么您也许可以指望它。
您应该知道使用的分隔符。打开文件时您应该能够看到它。如果文件来源每次都给你一个不同的分隔符并且不可靠,那么我很抱歉。 ;)
如果您只想使用不同的分隔符进行解析,那么您可以设置csv.Configuration.Delimiter
。 http://joshclose.github.io/CsvHelper/#configuration-delimiter
由于我不得不处理 CSV 文件(保存在 MS Excel 中)可能包含不同分隔符的可能性,具体取决于用户的本地化设置,我最终采用了以下方法:
public static string DetectDelimiter(StreamReader reader)
{
// assume one of following delimiters
var possibleDelimiters = new List<string> {",",";","\t","|"};
var headerLine = reader.ReadLine();
// reset the reader to initial position for outside reuse
// Eg. Csv helper won't find header line, because it has been read in the Reader
reader.BaseStream.Position = 0;
reader.DiscardBufferedData();
foreach (var possibleDelimiter in possibleDelimiters)
{
if (headerLine.Contains(possibleDelimiter))
{
return possibleDelimiter;
}
}
return possibleDelimiters[0];
}
我还需要重置 reader 的读取位置,因为它与我在 CsvReader 构造函数中使用的实例相同。
当时的用法如下:
using (var textReader = new StreamReader(memoryStream))
{
var delimiter = DetectDelimiter(textReader);
using (var csv = new CsvReader(textReader))
{
csv.Configuration.Delimiter = delimiter;
... rest of the csv reader process
}
}
有(至少现在)一个设置为 false 的 DetectDelimiter 值。 然后你可以添加你想测试的愿望分隔符,尽管默认是合理的