Comment gérer les streams non « seekable »

Bastien BRAILLY-VIGNAL
Catégorie : BizTalk
31/10/2018

 

J’ai récemment rencontré un problème en manipulant des streams dans un composant de pipeline BizTalk.

Apparemment, il arrive parfois que le stream utilisé ne soit pas « seekable » :

Erreur rencontrée :  ForwardOnlyEventingReadStream does not support Seek()

 

stream non seekable

 

Pour résoudre ce problème, il suffit « d’envelopper » le stream dans un « SeekableReadOnlyStream ».


public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
{
    try
    {
        //Do something [...]
        Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
        if (originalStream != null)
        {
            if (!originalStream.CanSeek) // check if originalStream can seek
            {
                SeekableReadOnlyStream seekableStream = new SeekableReadOnlyStream(originalStream); // create a new seekable stream
                seekableStream.Position = 0;
                pInMsg.BodyPart.Data = seekableStream; // set new stream for the body part data of the input message
                pInMsg.BodyPart.Data.Position = 0;
                originalStream = pInMsg.BodyPart.Data; // replace originalStream with a new seekable stream wrapper
            }
            else
            {
                originalStream.Seek(0, SeekOrigin.Begin);
            }
        }
        //Do something [...]
    }
    catch (Exception e)
    {
        throw new Exception("Error : " + e.Message);
    }
    return pInMsg;
}

Si vous traitez des données volumineuses, alors la classe VirtualStream est probablement la meilleure solution car, à partir du moment où la taille des données dépasse une certaine valeur, elle stocke les données sur le disque et non en mémoire.

Plus d’informations sur la gestion des streams dans BizTalk : https://mohamadhalabi.com/2013/12/29/biztalk-2013-streaming-support/.