使用 TextFieldParser 从流中解析 CSV 总是到达 EndOfData
Parsing CSV from stream with TextFieldParser always reaches EndOfData
在将 CSV 文件解析为来自 Azure Blob 的流期间,TextFieldParser 总是立即到达 EndOfData,而不读取任何数据。相同的代码,但使用相同物理文件的路径而不是流工作。
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(AzureStorageConnection)
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("containername").ListBlobs().OfType(Of CloudBlockBlob)
For Each blb In BlobList
Dim myList As New List(Of MyBusinessObject)
Using memoryStream = New MemoryStream()
blb.DownloadToStream(memoryStream)
Using Reader As New FileIO.TextFieldParser(memoryStream)
Reader.TextFieldType = FileIO.FieldType.FixedWidth
Reader.SetFieldWidths(2, 9, 10)
Dim currentRow As String()
While Not Reader.EndOfData
Try
currentRow = Reader.ReadFields()
myList.Add(New GsmXFileRow() With {
' code to read currentRow and add elements to myList
})
Catch ex As FileIO.MalformedLineException
End Try
End While
End Using
End Using
Next
我也尝试过将 MemoryStream
转换为 TextReader
Dim myTextReader As TextReader = New StreamReader(memoryStream)
然后将 myTextReader
传递给 TextFieldParser
,但这也不起作用。
Using Reader As New FileIO.TextFieldParser(myTextReader)
我看到了这个:
Value of Length property equals file size
还有这个:
'Position` property has same value
这意味着在循环开始时,MemoryStream
已经前进到流的末尾。只需将 Position
设置回 0,你应该在一个更好的地方。
但是,这里可能还有另一个问题。该流数据是二进制的,带有一些未知的编码。 TextFieldParser
想与 Text
一起工作。您需要一种方法来为 TextFieldParser
提供有关使用何种编码的信息。
在这种情况下,我推荐StreamReader
。此类型继承自 TextReader
,因此您可以将其与 TextFieldParser
一起使用:
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(AzureStorageConnection)
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("containername").ListBlobs().OfType(Of CloudBlockBlob)
Dim myList As New List(Of MyBusinessObject)
For Each blb In BlobList
'Several constructor overloads allow you to specify the encoding here
Using blobData As New StreamReader(New MemoryStream())
blb.DownloadToStream(blobData.Stream)
'Fix the position problem
blobData.Stream.Position = 0
Using Reader As New FileIO.TextFieldParser(blogData)
Reader.TextFieldType = FileIO.FieldType.FixedWidth
Reader.SetFieldWidths(2, 9, 10)
Dim currentRow As String() = Reader.ReadFields()
While Not Reader.EndOfData
Try
myList.Add(New GsmXFileRow() With {
' code to read currentRow and add elements to myList
})
currentRow = Reader.ReadFields()
Catch ex As FileIO.MalformedLineException
End Try
End While
End Using
End Using
Next
在将 CSV 文件解析为来自 Azure Blob 的流期间,TextFieldParser 总是立即到达 EndOfData,而不读取任何数据。相同的代码,但使用相同物理文件的路径而不是流工作。
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(AzureStorageConnection)
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("containername").ListBlobs().OfType(Of CloudBlockBlob)
For Each blb In BlobList
Dim myList As New List(Of MyBusinessObject)
Using memoryStream = New MemoryStream()
blb.DownloadToStream(memoryStream)
Using Reader As New FileIO.TextFieldParser(memoryStream)
Reader.TextFieldType = FileIO.FieldType.FixedWidth
Reader.SetFieldWidths(2, 9, 10)
Dim currentRow As String()
While Not Reader.EndOfData
Try
currentRow = Reader.ReadFields()
myList.Add(New GsmXFileRow() With {
' code to read currentRow and add elements to myList
})
Catch ex As FileIO.MalformedLineException
End Try
End While
End Using
End Using
Next
我也尝试过将 MemoryStream
转换为 TextReader
Dim myTextReader As TextReader = New StreamReader(memoryStream)
然后将 myTextReader
传递给 TextFieldParser
,但这也不起作用。
Using Reader As New FileIO.TextFieldParser(myTextReader)
我看到了这个:
Value of Length property equals file size
还有这个:
'Position` property has same value
这意味着在循环开始时,MemoryStream
已经前进到流的末尾。只需将 Position
设置回 0,你应该在一个更好的地方。
但是,这里可能还有另一个问题。该流数据是二进制的,带有一些未知的编码。 TextFieldParser
想与 Text
一起工作。您需要一种方法来为 TextFieldParser
提供有关使用何种编码的信息。
在这种情况下,我推荐StreamReader
。此类型继承自 TextReader
,因此您可以将其与 TextFieldParser
一起使用:
Dim storageAccount As CloudStorageAccount = CloudStorageAccount.Parse(AzureStorageConnection)
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
Dim BlobList As IEnumerable(Of CloudBlockBlob) = blobClient.GetContainerReference("containername").ListBlobs().OfType(Of CloudBlockBlob)
Dim myList As New List(Of MyBusinessObject)
For Each blb In BlobList
'Several constructor overloads allow you to specify the encoding here
Using blobData As New StreamReader(New MemoryStream())
blb.DownloadToStream(blobData.Stream)
'Fix the position problem
blobData.Stream.Position = 0
Using Reader As New FileIO.TextFieldParser(blogData)
Reader.TextFieldType = FileIO.FieldType.FixedWidth
Reader.SetFieldWidths(2, 9, 10)
Dim currentRow As String() = Reader.ReadFields()
While Not Reader.EndOfData
Try
myList.Add(New GsmXFileRow() With {
' code to read currentRow and add elements to myList
})
currentRow = Reader.ReadFields()
Catch ex As FileIO.MalformedLineException
End Try
End While
End Using
End Using
Next