使用TextFieldParser从流中解析CSV始终到达EndOfData

时间:2017-08-11 20:51:23

标签: vb.net csv stream blob textfieldparser

在将Azure文件解析为来自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)

1 个答案:

答案 0 :(得分:1)

我明白这一点:

  

长度属性的值等于文件大小

和此:

  

'Position`属性具有相同的值

这意味着在循环开始时,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