Чтение CSV-файла с OLEDB игнорирует первую строку, даже если HDR = Нет в строке подключения - PullRequest
0 голосов
/ 04 января 2011

Мы преобразуем классический сайт ASP в сайт ASP.NET. Одной из функций была загрузка «шаблона» данных в формате CSV для импорта в базу данных. Там было несколько разных типов записей (первое поле всегда идентифицирует тип данных).

Задача состояла в том, чтобы вставить CSV в DataTable, чтобы его можно было проверить (новый проект должен иметь НАМНОГО лучших правил проверки)

Код выглядел довольно простым - его разбавление (удаление комментариев, Try / Catch и т. Д.) Выглядит следующим образом:

    Dim da As New System.Data.OleDb.OleDbDataAdapter
    Dim cn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDirectory & ";" & "Extended Properties=""Text;HDR=No;FMT=Delimited;""")
    Dim cd As New System.Data.OleDb.OleDbCommand("SELECT * FROM " & strCSVFilename, cn)
    cn.Open()
    da.SelectCommand = cd
    da.Fill(dtData)

Заполняется DataTable (dtData), но только начиная со второй строки CSV-файла. УЖАСИТЕ тот факт, что в строке подключения указано «HDR = No».

Что мне здесь не хватает?

1 Ответ

1 голос
/ 05 января 2011

Возможно, в начале файла что-то пропускает первую строку?Может быть, непечатный символ?NPC может прийти из файла, который не был сохранен в ожидаемой кодировке.Когда я создал файл CSV, я получил результаты, которые вы ожидали.Вот код, который я использовал для тестирования:

    Private Sub Test()
    Dim TempDir = My.Computer.FileSystem.SpecialDirectories.Temp
    Dim TempFile = "Test.csv"

    '//Create our test file with a header row and three data rows
    Using FS As New System.IO.FileStream(System.IO.Path.Combine(TempDir, TempFile), IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Read)
        Using SW As New System.IO.StreamWriter(FS, System.Text.Encoding.ASCII)
            SW.WriteLine("Col1,Col2")
            SW.WriteLine("R1", "R1")
            SW.WriteLine("R2", "R2")
            SW.WriteLine("R3", "R3")
        End Using
    End Using

    '//Read the data into a table specifying that the first row should be treated as a header
    Using dtData As New DataTable()
        Using da As New System.Data.OleDb.OleDbDataAdapter
            Using cn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & TempDir & ";" & "Extended Properties=""Text;HDR=Yes;FMT=Delimited;""")
                Using cd As New System.Data.OleDb.OleDbCommand("SELECT * FROM " & TempFile, cn)
                    cn.Open()
                    da.SelectCommand = cd
                    da.Fill(dtData)
                    Trace.WriteLine("With header,    expected 3, found " & dtData.Rows.Count)
                End Using
            End Using
        End Using
    End Using

    '//Read the data into a table again, this time specifying that the there isn't a header row
    Using dtData As New DataTable()
        Using da As New System.Data.OleDb.OleDbDataAdapter
            Using cn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & TempDir & ";" & "Extended Properties=""Text;HDR=No;FMT=Delimited;""")
                Using cd As New System.Data.OleDb.OleDbCommand("SELECT * FROM " & TempFile, cn)
                    cn.Open()
                    da.SelectCommand = cd
                    da.Fill(dtData)
                    Trace.WriteLine("Without header, expected 4, found " & dtData.Rows.Count)
                End Using
            End Using
        End Using
    End Using

    '//Delete our temporary file
    System.IO.File.Delete(System.IO.Path.Combine(TempDir, TempFile))
End Sub

Если вы измените начальную кодировку на Unicode, вы получите 8 и 9 строк в результатах, а это, возможно, то, что вы видите.Если это окажется проблемой кодирования, вы можете добавить CharacterSet=Unicode в свои расширенные свойства.

...