使用 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