1

我正在为我们的应用程序开发一个新的缓冲处理器,并且重新审视了 ProtobufDeserialize*方法并使用以下代码进行了调查,在我以前的版本中,我在前面有自己的 TypeIdentifier 和 LengthPrefix,然后保证我有一个反序列化的完整块。为了测试,我已经用重复调用从写入磁盘的文件中读取随机长度块替换了对 networkStream 的读取SerializeWithLengthPrefix()

但是当我遍历 mDatabuffer 时,我会EndOfStreamException被抛出。这没什么大不了的,只是想确保我正确地执行了此操作,因为不能保证我将拥有一个“完整”的数据块来通过 Deserialize 调用完美地处理。我最初是在做 TryReadLengthPrefix,但这看起来更干净。

Public Sub New(ByVal maximumPacketSize As Integer)
    mMaxSize = maximumPacketSize
    mDataBuffer = New MemoryStream()
    mTypeResolver = AddressOf PacketTypeResolver
End Sub

Public Sub ProcessBuffer(ByVal theData() As Byte, offset As Integer, 
                         ByVal bytesToRead As Integer)
    'append the data we have just received into our StreamBuffer so we can 
    '"move back" if we hit the end of stream whilst Deserializing
    mDataBuffer.Seek(0, SeekOrigin.End)
    mDataBuffer.Write(theData, offset, bytesToRead)
    mDataBuffer.Seek(0, SeekOrigin.Begin)

    While mDataBuffer.Position < mDataBuffer.Length
        Dim currentPosition As Integer = CType(mDataBuffer.Position, Integer)
        Try
            Dim p As Object = Nothing
            If Serializer.NonGeneric.TryDeserializeWithLengthPrefix(mDataBuffer, 
                          PrefixStyle.Base128, mTypeResolver, p) Then
                If GetType(BasePacket).IsAssignableFrom(p.GetType) Then
                    Dim bufferedPacket As BasePacket = CType(p, BasePacket)
                    ''''Do stuff with the packet.
                End If
            End If
        Catch ex As EndOfStreamException
            Dim tmpData As New MemoryStream()
            tmpData.Write(mDataBuffer.GetBuffer(), currentPosition, 
                          CType(mDataBuffer.Length - currentPosition, Integer))
            mDataBuffer.Dispose()
            mDataBuffer = tmpData
            Exit While
        Catch ex As Exception
            Debug.Print(ex.GetType.Name & "---" & ex.Message)
            Throw
        End Try
    End While
End Sub 

(旁白)为了学习,我想知道不捕获内部异常的 API 设计决定TryDeserializeWithLengthPrefix

4

1 回答 1

0

Tryin不是“如果出现问题,TryDeserializeWithLengthPrefix尝试默默地放弃”,它是:“尝试从流中获取另一个对象,但如果我们在自然位置(对象之间)有一个 EOF,则返回 false”。如果数据非空但不完整或无效:它仍然会告诉您。高声。

如果您正在读取数据并且不知道您是否有一个完整的对象,那么我会说:

  • 编写自己的成帧协议,或
  • 用于TryReadLengthPrefix计算所需的长度,并缓冲那么多数据
于 2013-02-19T05:03:15.400 回答