2017-08-11 5 views
0

Azure BLOBからのストリームとしてCSVファイルを解析するとき、TextFieldParserは常にデータを読み込まずにEndOfDataにただちに到達します。同じコードですが、ストリームの代わりに同じ物理ファイルへのパスがあります。 TextFieldParserでストリームからCSVを解析すると、常に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 

は、私はまた、 TextFieldParsermyTextReaderを渡し、その後 TextReader

Dim myTextReader As TextReader = New StreamReader(memoryStream) 

とにMemoryStreamを変換しようとしたが、これはどちらか動作しません。

Lengthプロパティの値が等しいファイルサイズ

と、この:

Using Reader As New FileIO.TextFieldParser(myTextReader)

+0

には、ブレークポイントに入れて、あなたの 'memoryStream'は、あなたが期待するデータを持っていることを確認しましたか?また...あなたのTry/Catchブロックがキャッチされた例外を飲み込んでいるのが分かります。 Try/Catchなしでコードを実行して、エラーがスローされたかどうか確認してください。私は文字列にバイトを変換するエンコーディングの問題は、決して見るMalformedLineExceptionsの結果であると思われる。 –

+0

@JoelCoehoornはい。 'Length'プロパティの値はファイルのサイズと同じです。 'Position'プロパティはストリームがその端に位置することを示唆する値と同じ値を持ちます。例外として、 'Reader.EndOfData'は常に' True'であるため、コードは 'While'内で決して実行されません。 – Megrez7

+0

"位置プロパティに同じ値があります。"あなたの問題があります。それは既に蒸気の終わりまで読み込まれています。あなたは最初に元気に戻す必要があります。そして、あなたがそうするとき、私の答えをチェックしてください。エンコーディングの問題にも対処する必要があるかもしれません。 –

答えて

1

私はこの参照

「Position`プロパティが同じ値を持っている

これは、ループの開始時に、すでにMemoryStreamがストリームの最後に進んでいることを意味します。 Positionを0に戻すだけで、より良い場所にいるはずです。

ただし、こちらにも別の問題がある可能性があります。そのストリームデータは、未知のエンコーディングでバイナリです。 TextFieldParserTextと連携したいと考えています。 TextFieldParserに、使用されているエンコーディングに関する情報を与える方法が必要です。

この場合、私はStreamReaderをお勧めします。あなたはTextFieldParserでそれを使用することができますので、このタイプは、TextReaderから継承:

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 
+0

'rdrを新しいStreamReader(rdr)として使用する' ???私は、あなたがあなたの事例の一部の思考の列を残したと思います。また、 'TextFieldParser'はデフォルトのエンコーダーとエンコーディングを試して検出するように設定することもできます。 – TnTinMn

+0

@TnTinMn申し訳ありません...あなたは編集の間に私をつかまえました。もう一度見てください。 –

+1

SRのコンストラクタチェーンはストリームのエンコーディングを検出するので、 'StreamReader'に渡す前に' MemoryStream'を満たすのが良いと思います。それが空であれば問題があるかもしれません。しかし、 'TextFieldParser'が' Stream'と 'StreamReader'を構築するオプションのエンコーディングを受け入れることができるので、最初は' StreamReader'の必要性を理解していません。 – TnTinMn

関連する問題