我正在读取*.csv文件。
*.csv-file由分号(";")分隔的两列组成。
我能够阅读*.csv文件使用StreamReader,并能够通过使用Split()函数分离每一行。我想将每一列存储到一个单独的数组中,然后显示它。
有可能做到吗?
我正在读取*.csv文件。
*.csv-file由分号(";")分隔的两列组成。
我能够阅读*.csv文件使用StreamReader,并能够通过使用Split()函数分离每一行。我想将每一列存储到一个单独的数组中,然后显示它。
有可能做到吗?
当前回答
仍然是错误的。你需要对引号中的""进行补偿。 这是我的解决方案微软风格csv。
/// <summary>
/// Microsoft style csv file. " is the quote character, "" is an escaped quote.
/// </summary>
/// <param name="fileName"></param>
/// <param name="sepChar"></param>
/// <param name="quoteChar"></param>
/// <param name="escChar"></param>
/// <returns></returns>
public static List<string[]> ReadCSVFileMSStyle(string fileName, char sepChar = ',', char quoteChar = '"')
{
List<string[]> ret = new List<string[]>();
string[] csvRows = System.IO.File.ReadAllLines(fileName);
foreach (string csvRow in csvRows)
{
bool inQuotes = false;
List<string> fields = new List<string>();
string field = "";
for (int i = 0; i < csvRow.Length; i++)
{
if (inQuotes)
{
// Is it a "" inside quoted area? (escaped litteral quote)
if(i < csvRow.Length - 1 && csvRow[i] == quoteChar && csvRow[i+1] == quoteChar)
{
i++;
field += quoteChar;
}
else if(csvRow[i] == quoteChar)
{
inQuotes = false;
}
else
{
field += csvRow[i];
}
}
else // Not in quoted region
{
if (csvRow[i] == quoteChar)
{
inQuotes = true;
}
if (csvRow[i] == sepChar)
{
fields.Add(field);
field = "";
}
else
{
field += csvRow[i];
}
}
}
if (!string.IsNullOrEmpty(field))
{
fields.Add(field);
field = "";
}
ret.Add(fields.ToArray());
}
return ret;
}
}
其他回答
您可以使用c#中的Microsoft.VisualBasic.FileIO.TextFieldParser dll来获得更好的性能
从上面的文章中获取下面的代码示例
static void Main()
{
string csv_file_path=@"C:\Users\Administrator\Desktop\test.csv";
DataTable csvData = GetDataTabletFromCSVFile(csv_file_path);
Console.WriteLine("Rows count:" + csvData.Rows.Count);
Console.ReadLine();
}
private static DataTable GetDataTabletFromCSVFile(string csv_file_path)
{
DataTable csvData = new DataTable();
try
{
using(TextFieldParser csvReader = new TextFieldParser(csv_file_path))
{
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
LINQ:
var lines = File.ReadAllLines("test.txt").Select(a => a.Split(';'));
var csv = from line in lines
select (from piece in line
select piece);
^^错误-尼克编辑
原来的应答者似乎试图用一个2维数组填充csv -一个包含数组的数组。第一个数组中的每一项都包含一个表示行号的数组,嵌套数组中的每一项都包含该特定列的数据。
var csv = from line in lines
select (line.Split(',')).ToArray();
刚刚发现了这个库:https://github.com/JoshClose/CsvHelper
非常直观,易于使用。有一个nuget包也使快速实现:https://www.nuget.org/packages/CsvHelper/27.2.1。我很喜欢这种积极的保养。
将其配置为使用分号很容易:https://github.com/JoshClose/CsvHelper/wiki/Custom-Configurations
我一直在使用csvreader.com(付费组件)多年,我从来没有遇到过问题。它结实、小巧、快速,但你必须为此付费。您可以将分隔符设置为您喜欢的任何值。
using (CsvReader reader = new CsvReader(s) {
reader.Settings.Delimiter = ';';
reader.ReadHeaders(); // if headers on a line by themselves. Makes reader.Headers[] available
while (reader.ReadRecord())
... use reader.Values[col_i] ...
}
你可以这样做:
using System.IO;
static void Main(string[] args)
{
using(var reader = new StreamReader(@"C:\test.csv"))
{
List<string> listA = new List<string>();
List<string> listB = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(values[0]);
listB.Add(values[1]);
}
}
}