2009-09-22 18 views
24

ja nie potrafię odczytać plik .csv stosując następujący ciąg połączenia:C# odczyt pliku CSV nie daje poprawną ścieżkę

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(); 

To daje następujący błąd:

'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.

I zweryfikowali, że plik tam jest. Co tu się dzieje?

Odpowiedz

51

Ok, ja wykopał trochę dalej i wydaje się, że moje ciąg połączenia jest źle. W przypadku plików CSV nie podaje się rzeczywistej nazwy pliku, ale katalog, do którego należy, np.

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); 

I podajesz nazwę pliku w SelectCommand. Cóż za dziwny sposób. Teraz działa dla mnie.

+6

Należy również pamiętać, że jeśli używasz sterownika OLEDB systemu Microsoft Jet do odczytu plików CSV, nie będzie można odczytać żadnego pliku CSV, który ma więcej niż jedną kropkę w nazwie pliku. Oznacza to, że "filename.csv" zadziała, ale "file.name.csv" nie będzie. –

+0

Zwróć uwagę, że chcesz użyć 'sql = SELECT * FROM myfile.csv' (tzn. Nazwa pliku bez ścieżki). Możesz wyodrębnić nazwę pliku z pełnej ścieżki, używając 'csvFile = Right (csvPath, Len (csvPath) - InStrRev (csvPath," \ "))' –

+4

@ TommyO'Dell lub po prostu 'Path.GetFileName (csvPath)' –

2

Sposób łączenia ścieżek i nazw plików jest użycie:

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

w przykładzie:

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

nope, że nie działa tak dobrze – sean

+1

@seanlinmt: To nie jest jedynym problemem, ale jest to bardzo dobra rada. * Nigdy * nie manipuluj ścieżkami jako ciągami - zawsze używaj funkcji pomocnika 'System.IO.Path'. W przeciwnym razie zawsze będzie ten jedyny przypadek, który Cię ugryzie. –

0

Jeśli dysk D jest mapowany dysk sieciowy, a następnie być może trzeba użyć ścieżki UNC:

\\computerName\shareName\path\ 
1

miałem ten sam problem kilka tygodni temu próbował zrobić Office Automation 2007 i spędził zbyt dużo czas próbuje to naprawić.

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

Zalecam używanie parsera CSV zamiast korzystania z dostawcy danych OLEDB.

Wyszukaj, a znajdziesz wielu (bezpłatnych) kandydatów. Oto kilka z nich, który pracował dla mnie:

A portable and efficient generic parser for flat files (najłatwiejsze w użyciu, IMO)
A Fast CSV Reader (łatwy w użyciu, idealne dla dużych zbiorów danych)
FileHelpers biblioteki (elastyczne, obejmuje generatory kodu, trochę nauki krzywa)

Zazwyczaj umożliwiają one określenie właściwości pliku CSV (ogranicznik, nagłówek, kwalifikator tekstu itp.) oraz wywołanie metody, w wyniku której plik CSV zostanie zrzucony do struktury danych, takiej jak DataTable lub Lista <>.

Jeśli będziesz pracować w ogóle z CSV, warto sprawdzić parser CSV.

+3

Użyłem "Szybkiego czytnika CSV", jest świetny. –

+1

Chociaż zgadzam się, że użycie parsera CSV jest prawdopodobnie najlepszym rozwiązaniem (zobacz moją odpowiedź na alternatywę, która jest już wbudowana w system .NET Framework), mogą zdarzyć się sytuacje, w których używanie sterownika OLEDB firmy Microsoft Jet jest użyteczne. Jedną z użytecznych właściwości jest to, że potrafi ona wykryć typy danych kolumn CSV, z których korzystałem w przeszłości podczas pisania kodu do tłumaczenia plików CSV na inny format (DBF w moim przypadku). –

+0

@Daniel - Ciekawi mnie dostawca OLEDB, nie wiedziałem o tym. Nie jestem pewien, czy chciałbym skorzystać z tej funkcji, woląc jawnie ustawić (i sprawdzić) te rzeczy osobiście. Dzięki za informację. –

2

Jeśli próbujesz odczytać plik CSV za pomocą C#, najłatwiej jest użyć klasy Microsoft.VisualBasic.FileIO.TextFieldParser. Jest faktycznie wbudowany w .NET Framework, zamiast być rozszerzeniem innej firmy.

Tak, jest w Microsoft.VisualBasic.dll, ale to nie znaczy, że nie można go używać z języka C# (lub dowolnego innego języka CLR).

Oto przykład użycia, zaczerpnięte z 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 

Ponownie, ten przykład jest w VB.NET, ale byłoby trywialne tłumaczyć go do C#.