Vb.net 使用OleDb导入时正在修剪CSV字符串
我正在用oledb机制读取csv文件。我的主要问题是,读取时csv中的字符串值正在被修剪(同时:在begging和结尾处都有空格)。我在csv文件中有一些特定的数据,只有在某些情况下才需要有这样的空白-这就是为什么我在处理后无法处理这些数据的原因。这必须通过转换来完成 不幸的是,这必须通过oledb和vb.net来完成,因为我们的复杂机制是基于这些技术的 有没有可能找到一个oledb不会修剪我的字符串的破解或解决方法 以下是我的代码、实际结果和预期结果: csv文件:Vb.net 使用OleDb导入时正在修剪CSV字符串,vb.net,csv,oledb,trim,Vb.net,Csv,Oledb,Trim,我正在用oledb机制读取csv文件。我的主要问题是,读取时csv中的字符串值正在被修剪(同时:在begging和结尾处都有空格)。我在csv文件中有一些特定的数据,只有在某些情况下才需要有这样的空白-这就是为什么我在处理后无法处理这些数据的原因。这必须通过转换来完成 不幸的是,这必须通过oledb和vb.net来完成,因为我们的复杂机制是基于这些技术的 有没有可能找到一个oledb不会修剪我的字符串的破解或解决方法 以下是我的代码、实际结果和预期结果: csv文件: Column1|Colum
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
代码
实际结果:
|Text1|
|Text2|
|Text3|
|Text4|
预期成果:
|Text1 |
| Text2|
| Text3 |
|Text4|
另外,我在schema.ini中尝试了不同的设置:编码、MaxScanRows、固定宽度,但没有任何帮助。尝试一下……但无法保证,因为我没有进行任何错误处理
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
我想在处理数据库时,尾随空格有一个普遍的问题:一些字符数据类型使用空格来填充其余的字符。对于MSSql,有一个选项ANSI PADDING,您可以打开/关闭它,但我看不到一种方法可以为我们用于CSV文件的Microsoft JET Engine设置该选项;我们同时支持oledb和odbc,这两个版本都存在这个问题 所以,答案是你不能。从CSV数据源导入数据时,始终会删除尾随空格,无论是为列定义text/char/memo数据类型(例如使用schema.ini)还是将字符串括在双引号中。你可以在末尾加上一些特殊的字符(非空格),比如tab
我看不到连接字符串中指定的格式:
extendedproperties=“text;HDR=YES;FMT=FixedLength”
。然后,正如您已经知道的,您必须使用schema.ini@jimi格式在模式文件中。如果您要读取整个文件,并且不对其进行查询,那么我建议您将该文件读取到数据表中。OLE DB CSV已启用ansi填充,无法解决问题。@brax您已完全破坏了OP的输出。抱歉,但我已提到oledb连接是必需的,因为它稍后将在其他方法中用作参数。@Arsey祝您玩得开心。我想你还没有读过这篇文章microsoft@Arsey我将保留代码,因为它可能对其他人有用。你不必投票否决它。你可以留言instead@Arsey您知道,如果您使用您的一些想象力,将数据表保存到MS access DB,并使用到access DB的ole连接传递到其他方法。我甚至不认为前面有空间的目的。我知道你想把它们留到最后。。。。
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