前面兩項vb.net+LinqToCSV的應用,
沒什麼困難。但後面因為不同的設備,要用到不同的class但邏輯都一樣。
想說就來用泛型好了,結果…..燒的我一個頭兩個大。
泛型用完,還要用反射來動態取class的Property燒的我頭又更大了。
泛型+反射 還有很多未解的問題,還需慢慢研究。
此文章會用到徐大寫的LinqToCSV介紹
但我用的是vb.net,為了以後的人…...
基本的語法會像這樣子
Dim cv As CsvFileDescription = New CsvFileDescription() With
{
.SeparatorChar = ",",
.FirstLineHasColumnNames = False,
.EnforceCsvColumnAttribute = True,
.IgnoreUnknownColumns = True '//該死的選項害我卡關卡了整整4個小時
}
Dim cc As CsvContext = New CsvContext()
Dim Stream As FileStream = New FileStream(ReadFiles, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Using reader As StreamReader = New StreamReader(Stream, System.Text.Encoding.UTF8)
Dim pp = cc.Read(Of disCharge12)(reader, cv)
End Using
Read後面會接class,讓csv能夠跟他對應。
要注意的是 IgonreUnknowColumns ,
有另一個長得很像的參數IgnoreTrailingSeparatorChar
要忽略不同的col預設是false,如果沒設true,要麻就是你的class寫的剛剛好,
一比一的都有對到。不然真的抓不到原因。
下面是泛型+反射設定欄位
Private Function getCSVData(Of T As {Class, New})(ByVal ReadFiles As String, ByVal col As T)
Dim CountsZero As Integer = 0
Try
Dim cv As CsvFileDescription = New CsvFileDescription() With
{
.SeparatorChar = ",",
.FirstLineHasColumnNames = False,
.EnforceCsvColumnAttribute = True,
.IgnoreUnknownColumns = True '///////該死的選項害我卡關卡了整整4個小時
}
Dim cc As CsvContext = New CsvContext()
Dim Stream As FileStream = New FileStream(ReadFiles, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
Using reader As StreamReader = New StreamReader(Stream, System.Text.Encoding.UTF8)
Dim pp = cc.Read(Of T)(reader, cv)
Dim list = pp.ToList
For Each ss In list
'此段為建立一個新的class,但目前只需要將原始的檔案名稱加上fileName的值
'Dim oTemp As Object = System.Activator.CreateInstance(System.Type.GetType(className))
Dim uTemp As Object = ss
Dim uType As Type = ss.GetType
Dim uProperty As Reflection.PropertyInfo = uType.GetProperty("fileName")
uProperty.SetValue(uTemp, FileNames)
'msg(ss.ToString)
Next
Return list
End Using
End Function
使用方式
Dim condition = 3
Dim list
If condition = 3 Then
list = getCSVData(Of disCharge3)(ReadFiles, New disCharge3)
Else
list = getCSVData(Of disCharge16)(ReadFiles, New disCharge16)
End If
Readfile 是檔案位置
值取出來後,如果直接指定類別,可以直接印出。
For Each pp As disCharge3 In list
msg(pp.fileName)
Next
如果不想指定類別,就仍然必須使用反射的方式取得要輸出的名稱
For Each pp In list
'利用反射的方式取值
Dim uTemp As Object = pp
Dim uType As Type = pp.GetType
Dim uProperty As Reflection.PropertyInfo = uType.GetProperty("fileName")
Dim fileName = uProperty.GetValue(uTemp)
msg(fileName)
Next
class的名稱結構像這樣
Public Class disCharge3
Inherits charge
<CsvColumn(FieldIndex:=1)>
Public Property batteryType As String
<CsvColumn(FieldIndex:=2, CanBeNull:=True)>
Public Property batteryLot As String
<CsvColumn(FieldIndex:=3, CanBeNull:=True)>
Public Property batteryAmp As String
<CsvColumn(FieldIndex:=4, CanBeNull:=True)>
Public Property status As String
<CsvColumn(FieldIndex:=5, CanBeNull:=True)>
Public Property cstype As String
<CsvColumn(FieldIndex:=6, CanBeNull:=True)>
Public Property fileName As String
End Class
0 意見:
張貼留言