2009-09-22 43 views
24

我似乎无法使用下面的连接字符串来读取.csv文件:C#阅读csv文件给出了不是有效的路径

var fileName = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, "Uploads\\countrylist.csv"); 
string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}; Extended Properties=""text;HDR=YES;FMT=Delimited""", fileName); 
OleDbConnection oledbConn = new OleDbConnection(connectionString); 
oledbConn.Open(); 

它提供了以下错误:

'D:\arrgh\arrgh\Uploads\countrylist.csv' is not a valid path. Make sure that the path name is spelled correctly and that you are connected to the server on which the file resides.

我验证该文件在那里。这里发生了什么?

回答

51

好吧,我挖了一个远一点,似乎我的连接字符串是错误的。对于CSV文件,您不指定实际的文件名,而是指定它所属的目录,例如。

var fileName = string.Format("{0}{1}", AppDomain.CurrentDomain.BaseDirectory, "Uploads\\"); 
string connectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}; Extended Properties=""text;HDR=YES;FMT=Delimited""", fileName); 
OleDbConnection oledbConn = new OleDbConnection(connectionString); 
oledbConn.Open(); 
var cmd = new OleDbCommand("SELECT * FROM [countrylist.csv]", oledbConn); 

然后在SelectCommand中指定文件名。这是多么奇怪的做法。现在它为我工作。

+6

另请注意,如果您使用Microsoft Jet OLEDB驱动程序读取CSV文件,则无法读取其文件名中具有多个点的任何CSV文件。也就是说,“filename.csv”将起作用,但“file.name.csv”不会。 – 2009-09-22 05:36:05

+0

并注意你想使用'sql = SELECT * FROM myfile.csv'(即没有路径的文件名)。您可以使用'csvFile = Right(csvPath,Len(csvPath) - InStrRev(csvPath,“\”))' – 2011-10-13 02:31:35

+4

@ TommyO'Dell或简单地'Path.GetFileName(csvPath)' – 2013-04-05 19:59:01

2

为路径和文件名的组合方式是使用:

fullFilename = System.IO.Path.Combine(folderfilepath, Filename); 

在你的榜样:

var fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Uploads\countrylist.csv"); 
+0

不,不工作,以及 – sean 2009-09-22 04:59:48

+1

@seanlinmt:这不是你的唯一的问题,但是这是非常中肯的意见。 *从不*作为字符串进行路径操作 - 始终使用'System.IO.Path'辅助函数。否则,总会有一个咬你的边缘案例。 – 2009-09-22 05:44:40

0

如果d驱动器映射网络驱动器,那么你可能需要使用UNC路径:

\\computerName\shareName\path\ 
1

我几个星期前,有同样的问题试图做一些Office 2007的自动化和花费太多试图修复它。

string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=YES;IMEX=1;\""; 
4

我建议您使用CSV解析器而不是使用OLEDB数据提供程序。

搜索,你会发现许多(免费)的候选人。这里是为我工作的几个:

A portable and efficient generic parser for flat files(最容易使用,IMO)
A Fast CSV Reader(易于使用,非常适合大型数据集)
FileHelpers库(灵活,包括代码生成器,一个学习的位曲线)

通常,这些将允许您指定CSV(分隔符,标题,文本限定符等)的属性,并通过方法调用您的CSV转储到某种数据结构,如DataTable或列表<>。

如果您完全可以使用CSV工作,则需要查看CSV解析器。

+3

我用过“Fast CSV Reader”,很棒。 – 2009-09-22 05:45:20

+1

尽管我同意使用CSV解析器可能是最好的解决方案(请参阅我的答案,以了解实际内置于.NET Framework中的替代方案),但可能会出现使用Microsoft Jet OLEDB驱动程序的情况。一个有用的属性是,它可以检测CSV列的数据类型,在编写代码将CSV文件转换为其他格式(本例中为DBF)时,我曾使用这些数据类型。 – 2009-09-22 05:47:17

+0

@Daniel - 对OLEDB供应商感兴趣,我不知道。我不确定我是否想要使用此功能,但愿意自己明确设置(并检查)这些内容。谢谢(你的)信息。 – 2009-09-22 06:13:03

2

如果您只是想用C#读取CSV文件,最简单的方法就是使用Microsoft.VisualBasic.FileIO.TextFieldParser类。它实际上内置于.NET Framework中,而不是第三方扩展。

是的,它在Microsoft.VisualBasic.dll,但这并不意味着你不能从C#(或任何其他CLR语言)使用它。

下面是使用的例子,从MSDN documentation采取:

Using MyReader As New _ 
Microsoft.VisualBasic.FileIO.TextFieldParser("C:\testfile.txt") 
    MyReader.TextFieldType = FileIO.FieldType.Delimited 
    MyReader.SetDelimiters(",") 
    Dim currentRow As String() 
    While Not MyReader.EndOfData 
     Try 
     currentRow = MyReader.ReadFields() 
     Dim currentField As String 
     For Each currentField In currentRow 
      MsgBox(currentField) 
     Next 
     Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException 
     MsgBox("Line " & ex.Message & _ 
     "is not valid and will be skipped.") 
     End Try 
    End While 
End Using 

同样,这个例子是VB.NET,但它是微不足道将其翻译为C#。