[英]Error trying to read csv file
美好的一天,
我在讀取asp.net項目上的csv文件時遇到問題。
它總是返回錯誤索引超出范圍,無法找到第6列
在繼續解釋我在這里所做的工作之前,代碼是:
string savepath;
HttpPostedFile postedFile = context.Request.Files["Filedata"];
savepath = context.Server.MapPath("files");
string filename = postedFile.FileName;
todelete = savepath + @"\" + filename;
string forex = savepath + @"\" + filename;
postedFile.SaveAs(savepath + @"\" + filename);
DataTable tblcsv = new DataTable();
tblcsv.Columns.Add("latitude");
tblcsv.Columns.Add("longitude");
tblcsv.Columns.Add("mps");
tblcsv.Columns.Add("activity_type");
tblcsv.Columns.Add("date_occured");
tblcsv.Columns.Add("details");
string ReadCSV = File.ReadAllText(forex);
foreach (string csvRow in ReadCSV.Split('\n'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
tblcsv.Rows.Add();
int count = 0;
foreach (string FileRec in csvRow.Split('-'))
{
tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
count++;
}
}
}
我嘗試使用逗號分隔的列,但隨附的字符串包含逗號,因此我嘗試使用-符號只是為了確保文本文件上沒有多余的逗號,但彈出相同的錯誤。
難道我做錯了什么?
先感謝您
您的excel文件中一行或多行的列數可能超過6。 因此,在內部foreach中拆分會發現更多列,但tblcsv的列數不能超過6以分配額外的列值。
嘗試這樣的事情:
foreach (string FileRec in csvRow.Split('-'))
{
if(count > 5)
return;
tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
count++;
}
但是,最好在處理並處理問題之前檢查其他列。
StringBuilder errors = new StringBuilder(); //// this will hold the record for those array which have length greater than the 6
foreach (string csvRow in ReadCSV.Split('\n'))
{
if (!string.IsNullOrEmpty(csvRow))
{
//Adding each row into datatable
DataRow dr = tblcsv.NewRow(); and then
int count = 0;
foreach (string FileRec in csvRow.Split('-'))
{
try
{
dr[count] = FileRec;
tblcsv.Rows.Add(dr);
}
catch (IndexOutOfRangeException i)
{
error.AppendLine(csvRow;)
break;
}
count++;
}
}
}
現在,在這種情況下,我們將了解導致錯誤的csv行,其余的將成功處理。 驗證錯誤的行是否是所需的輸入,如果不是,則更正csv文件中的值。
如果分隔符出現在字段中,則不能將文件視為CSV。 在這種情況下,您可以使用正則表達式提取前五個字段到破折號,然后將行的其余部分讀取為第六個字段。 使用正則表達式,您可以匹配整個字符串,甚至可以避免分割線。
正則表達式也比拆分快得多,並且由於不創建臨時字符串,因此占用更少的內存。 這就是為什么它們被廣泛用於解析日志文件的原因。 通過名稱捕獲字段的能力也不會受到損害
下面的示例分析整個文件,並捕獲命名組中的每個字段。 最后一個字段捕獲到行尾的所有內容:
var pattern="^(?<latitude>.*?)-(?<longitude>.*?)-(?<mps>.*?)-(?<activity_type>.*?)-" +
"(?<date_occured>.*?)-(?<detail>.*)$";
var regex=new Regex(pattern,RegexOptions.Multiline);
var matches=regex.Matches(forex);
foreach (Match match in matches)
{
DataRow dr = tblcsv.NewRow();
row["latitude"]=match.Groups["latitude"].Value);
row["longitude"]=match.Groups["longitude"].Value);
...
tblcsv.Rows.Add(dr);
}
(?<latitude>.*?)-
模式將直到第一個破折號的所有內容捕獲到名為latitude
的組中。 .*?
模式意味着匹配是不貪,即它不會嘗試捕捉一切該行的結束,但將停止在第一-
遇到。
列名與字段名匹配,這意味着您可以使用循環添加所有字段:
foreach (Match match in matches)
{
var row = tblCsv.NewRow();
foreach (Group group in match.Groups)
{
foreach (DataColumn col in tblCsv.Columns)
{
row[col.ColumnName]=match.Groups[col.ColumnName].Value;
}
}
tblCsv.Rows.Add(row);
}
tblCsv.Rows.Add(row);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.