2011-01-20 11 views
0

着信ストリームは固定された1024バイトのバッファーに入っています。ストリーム自体はハグXMLファイルであり、終了するまでに数回の読み取りが必要です。私の目標は、バッファを読み込んで、大きなXMLファイルで要素が何回発生したかを把握することです。固定長バッファから読み取るXmlReader

私のchanllengeは本当に固定長バッファーなので、XmlTextReaderでストリームをラップすると、XMLのwellformを保証することができません。常に例外を受け取り、読み込みを完了できません。たとえば、要素はabcdefになりますが、第1バッファはabcで終了し、第2バッファはdefで始まります。私は本当にこのことについて不満を抱いています。誰もがストリーミング・ファッションを使ってこれを成し遂げる良い方法をアドバイスできますか?これは通常、それはより多くの「要素をカウントではなく、メモリに全体のXMLを読み込む」のようなものです...一種の奇妙な目標です

+0

XmlTextReaderはソリューションでなければなりません。手動で行うのではなく、バッファを管理させるだけです。 – porges

答えて

0

そんなに

おかげで(私は、メモリ内のコンテンツ全体をロードする必要はありません)簡単なのは、通常、XmlReaderを使用してXmlDocumentを使用してXMLを読み込み(つまりLINQを使用して)、NetworkStreamと同様の順方向ストリームとしてバッファを表すStream派生クラスを作成します。

あなたの目標を明確にすれば、他の人にアドバイスする方が簡単かもしれません。

+0

お返事ありがとうございました。このシナリオでは、BizTalkのパイプラインコンポーネントのイベントハンドラにコードを記述します。実行時に、BizTalkエンジンはダウンストリームデータ(xml形式)を読み込み、イベントを発生させ、イベントハンドラに固定長のバッファを供給します。私の目標は、このバッファを何とかして特定の要素をカウントすることです。しかし、これの挑戦は、部分的なnonwellformed xmlが内部にある可能性があるため、バッファ内に何があるかという保証はありません。 – NINIThePug

+0

しかし、メモリ内のドキュメント全体をバッファリングすることがオプションであれば、ドキュメントを処理する仕事はぼんやりと簡略化されます。 –

+0

はオプションではありません。メッセージあたり100メガバイトをバッファリングすることについては、ハードウェアに犯罪を犯していると考えてください。 – NINIThePug

1

1024バイトのバッファは、System.IO.Streamの標準的な具体的な実装の1つから来ていますか?あなたがする必要がある - と言う、例えば、あなたがAPIのいくつかの並べ替えからバッファを「読み」している - そうでない場合

XmlTextReader tr = XmlTextReader.Create(myStreamInstance) ; 

:トン使用されている場合は、あなただけの基本ストリームの周りにあなたのXmlTextReaderを作成することができます次に、上記のように、あなたのXmlReaderをインスタンス化

public class MyStream : System.IO.Stream 
{ 
    public override bool CanRead { get { return true ; } } 
    public override bool CanSeek { get { return false ; } } 
    public override bool CanWrite { get { return false ; } } 
    public override long Length { get { throw new NotImplementedException(); } } 
    public override long Position { 
            get { throw new NotImplementedException(); } 
            set { throw new NotImplementedException(); } 
            } 

    public override int Read(byte[] buffer , int offset , int count) 
    { 
     int bytesRead = 0 ; 

     if (!initialized) 
     { 
      Initialize() ; 
     } 

     for (int bytesRemaining = count ; !atEOF && bytesRemaining > 0 ;) 
     { 

      int frameRemaining = frameLength - frameOffset ; 
      int chunkSize  = (bytesRemaining > frameRemaining ? frameRemaining : bytesRemaining) ; 

      Array.Copy(frame , offset , frame , frameOffset , chunkSize) ; 

      bytesRemaining -= chunkSize ; 
      offset   += chunkSize ; 
      bytesRead  += chunkSize ; 

      // read next frame if necessary 
      if (frameOffset >= frameLength) 
      { 
       ReadNextFrame() ; 
      } 

     } 

     return bytesRead ; 
    } 

    public override long Seek(long offset , System.IO.SeekOrigin origin) { throw new NotImplementedException(); } 
    public override void SetLength(long value)       { throw new NotImplementedException(); } 
    public override void Write(byte[] buffer , int offset , int count) { throw new NotImplementedException(); } 
    public override void Flush()           { throw new NotImplementedException(); } 

    private byte[] frame  = null ; 
    private int frameLength = 0  ; 
    private int frameOffset = 0  ; 
    private bool atEOF  = false ; 
    private bool initialized = false ; 

    private void Initialize() 
    { 
     if (initialized) throw new InvalidOperationException() ; 

     frame  = new byte[1024] ; 
     frameLength = 0 ; 
     frameOffset = 0 ; 
     atEOF  = false ; 
     initialized = true ; 

     ReadNextFrame() ; 

     return ; 
    } 

    private void ReadNextFrame() 
    { 

     //TODO: read the next (or first 1024-byte buffer 
     //TODO: set the frame length to the number of bytes actually returned (might be less than 1024 on the last read, right? 
     //TODO: set the frame offset to 0 
     //TODO: set the atEOF flag if we've exhausted the data source ; 

     return ; 

    } 

} 

::、これらの行(あなたがする必要がある必要があり、すべてがReadNextFrame肉付け()メソッドで、おそらくあなたのコンストラクタを実装する)に沿って何かを自分自身の具体的な流れを実装

System.IO.Stream  s = new MyStream() ; 
System.Xml.XmlReader xr = XmlTextReader.Create(s) ; 

乾杯!

関連する問題