我正在使用oledb机制阅读csv文件。我的主要问题是在读取时csv中的字符串值正在被修剪(两者:在开始和结束时都有空格)。我在csv文件中有一些特定的数据,在某些情况下需要有这样的空格 - 这就是我在处理后无法处理的原因。它必须通过转换来完成。
不幸的是,由于我们的复杂机制基于这些技术,因此必须使用oledb和vb.net。
是否有可能找到oledb不会修剪我的字符串的黑客或解决方法?
以下是我的代码,实际结果和预期:
csv文件:
Column1|Column2|Column3|Column4
Text1 | Text2| Text3 |Text4
SCHEMA.INI
[test.csv]
Format=Delimited(|)
Col1=Column1 Text
Col2=Column2 Text
Col3=Column3 Text
Col4=Column4 Text
代码
Private conn As New OleDbConnection
Private cmd As New OleDbCommand
Private myAccessDataReader As OleDb.OleDbDataReader = Nothing
Sub Main()
Try
Dim dirInfo As String = "C:\csv"
If conn.State = ConnectionState.Open Then
conn.Close()
End If
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & dirInfo & ";Extended Properties=""Text;HDR=Yes;"";"
conn.Open()
cmd = New OleDbCommand("SELECT * From [test.csv]", conn)
myAccessDataReader = cmd.ExecuteReader()
If myAccessDataReader.HasRows Then
myAccessDataReader.Read()
End If
Console.WriteLine("|" + myAccessDataReader.Item("Column1") + "|")
Console.WriteLine("|" + myAccessDataReader.Item("Column2") + "|")
Console.WriteLine("|" + myAccessDataReader.Item("Column3") + "|")
Console.WriteLine("|" + myAccessDataReader.Item("Column4") + "|")
Console.ReadKey()
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
实际结果:
|Text1|
|Text2|
|Text3|
|Text4|
预期结果:
|Text1 |
| Text2|
| Text3 |
|Text4|
聚苯乙烯。我尝试过schema.ini中的不同设置:encoding,MaxScanRows,固定宽度,但没有任何帮助。
答案 0 :(得分:0)
我想在处理数据库时有一个跟踪空格的一般问题:一些char数据类型使用空格来填充其余的字符。对于MSSql,有一个选项ANSI PADDING,你可以打开/关闭,但我没有看到为我们用于CSV文件的Microsoft JET引擎设置的方法;我们支持oledb和odbc,这个问题都存在。
所以,答案是你不能。无论是否为列定义text / char / memo数据类型(例如,使用schema.ini)或将字符串括在双引号中,当您从CSV数据源导入数据时,将始终删除尾随空格。例如,您可以在空格之后放置一些特殊字符(非空格),例如制表符。
答案 1 :(得分:-1)
试试这个.....但由于我没有做任何错误处理,因此无法保证......
Function ReadCSVToTable(ByVal Schema As String) As DataTable
Dim file As New StreamReader("C:\dump\" & Schema)
Dim CSVName As String = file.ReadLine()
CSVName = Strings.Mid(CSVName, 2, CSVName.Length - 2)
Dim Delimiter As String = file.ReadLine
Delimiter = Strings.Mid(Delimiter, Strings.InStr(Delimiter, "(") + 1, Delimiter.Length - Strings.InStr(Delimiter, ")") + 1)
Dim Buffer As String = ""
Dim xtable As New DataTable
xtable.TableName = CSVName
'create table
Do
Buffer = file.ReadLine
Dim xCol As New DataColumn
With xCol
.ColumnName = Buffer.Split("=")(0)
.Caption = Buffer.Split("=")(1).Split(" ")(0)
Select Case Buffer.Split("=")(1).Split(" ")(1).ToLower
Case "text"
.DataType = GetType(String)
Case "integer"
.DataType = GetType(Integer)
Case "decimal"
.DataType = GetType(Decimal)
Case "boolean"
.DataType = GetType(Boolean)
Case Else
.DataType = GetType(String)
End Select
End With
xtable.Columns.Add(xCol)
Loop Until file.EndOfStream = True
file.Close()
file.Dispose()
'Fill the table
file = New StreamReader("C:\dump\" & CSVName)
'skip header
Buffer = file.ReadLine
Do
Buffer = file.ReadLine
Dim xCol(xtable.Columns.Count - 1)
Dim xCount As Integer = 0
For Each tCol As DataColumn In xtable.Columns
Select Case tCol.DataType
Case GetType(String)
xCol(xCount) = Convert.ToString(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case GetType(Integer)
xCol(xCount) = Convert.ToInt64(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case GetType(Decimal)
xCol(xCount) = Convert.ToDecimal(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case GetType(Boolean)
xCol(xCount) = Convert.ToBoolean(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
Case Else
xCol(xCount) = Convert.ToString(Buffer.Split(New String() {Delimiter}, StringSplitOptions.None)(xCount))
End Select
xCount = xCount + 1
Next
xtable.Rows.Add(xCol)
Loop Until file.EndOfStream = True
file.Close()
file.Dispose()
Return xtable
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim CSVTable As DataTable = ReadCSVToTable("schema.ini")
End Sub