延伸一般檔案解譯器管線元件
下列範例說明如何建立自訂解譯器,以剖析使用 UTF-7 編碼的一般檔案文件。 若要處理 UTF-7 檔,元件會繼承自 FFDasmComp 類別,然後覆寫其 GetDataReader 方法。
using System;
using System.Text;
using System.IO;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.ParsingEngine;
using Microsoft.BizTalk.Component;
using System.Runtime.InteropServices;
namespace Microsoft.BizTalk.Test
{
/// <summary>
/// Implements FF disassembler which always uses UTF-7 encoding.
/// </summary>
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
[ComponentCategory(CategoryTypes.CATID_Streamer)]
[Guid("A6E5F54F-7902-4e1a-84D8-5C7584F0ECF2")]
public class Utf7FFDasm :
FFDasmComp,
IBaseComponent
{
/// <summary>
/// Initializes a Utf7FFAsmDasm instance.
/// </summary>
public Utf7FFDasm()
{
}
/// <summary>
/// Name property
/// </summary>
public new string Name
{
get
{
return "UTF-7 FlatFile Disassembler";
}
}
/// <summary>
/// Version property
/// </summary>
public new string Version
{
get
{
return "1.0";
}
}
/// <summary>
/// Description property
/// </summary>
public new string Description
{
get
{
return "UTF-7 FlatFile Disassembler";
}
}
/// <summary>
/// Gets a data reader instance
/// </summary>
/// <param name="dataStream">Data stream</param>
/// <param name="dataEncoding">Data encoding</param>
/// <param name="detectEncodingFromByteOrderMarks">Detect encoding from a byte order mark</param>
/// <returns>IDataReader instance</returns>
protected override IDataReader GetDataReader(Stream dataStream, Encoding dataEncoding, bool detectEncodingFromByteOrderMarks)
{
// Delegate call to the base implementation passing fixed UTF-7 encoding
return base.GetDataReader(dataStream, Encoding.UTF7, false);
}
}
}
範例
下列範例說明如何建立自訂解譯器,以進行一般檔案交換的交易處理。 不同於標準的「一般檔案解譯器」,在完全處理過整個輸入交換之前,該解譯器不會產生任何解譯的文件。 此元件實作繼承自 FFDasmComp 類別,並覆寫 GetNext 方法。 在第一次呼叫GetNext方法時,它會處理交換中的所有訊息、將它們儲存在ArrayList中,並從ArrayList傳回第一個訊息。 在後續呼叫時,它會從 ArrayList傳回下一則訊息。
注意
以下程式碼範例中,GetNext() 方法的實作應該不適合處理大型文件,因為此實作會傳回記憶體中的整個交換。 對於大型文件使用這項技巧便可能會耗盡記憶體資源,而且會造成效能降低或行為不穩定。
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using Microsoft.BizTalk.Component;
namespace Microsoft.BizTalk.Component
{
/// <summary>
/// Summary description for Class1.
/// </summary>
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_DisassemblingParser)]
[Guid("EB4714A8-FD97-43de-84E2-E011648F349B")]
public class TransactionalFFDasm :
FFDasmComp,
IBaseComponent,
IDisassemblerComponent
{
public TransactionalFFDasm()
{
}
#region IBaseComponent Members
public new string Description
{
get
{
return "Transactional Flat File Disassembler";
}
}
public new string Name
{
get
{
return "Transactional Flat File Disassembler";
}
}
public new string Version
{
get
{
return "1.0";
}
}
#endregion
#region IDisassemblerComponent Members
public new void Disassemble(IPipelineContext pContext, IBaseMessage pInMsg)
{
base.Disassemble(pContext, pInMsg);
}
public new IBaseMessage GetNext(IPipelineContext pContext)
{
// Check if don't need to stop collecting messages
if (currentMessage == 0)
{
messageInterchange = new ArrayList();
currentMessage = 0;
// Collect messages from the standard disassembler
IBaseMessage disassembledMessage = null;
while ((disassembledMessage = base.GetNext(pContext)) != null)
{
byte[] buffer = new byte[4096];
int count = 0;
// Create a new memory stream to contain the disassembled message.
MemoryStream messageStream = new MemoryStream();
// Get a stream pointer to the disassembled stream.
Stream disassembledStream = disassembledMessage.BodyPart.GetOriginalDataStream();
// Write the disassembled message to the memory stream
while (0 != (count == disassembledStream.Read(buffer, 0, 4096)))
{
messageStream.Write(buffer, 0, count);
} // end-while
// Rewind the stream to the beginning
messageStream.Seek(0, SeekOrigin.Begin);
// Replace the stream on the disassembled message with the memory stream.
disassembledMessage.BodyPart.data = messageStream;
// Add this message to the ArrayList of messages.
messageInterchange.Add(disassembledMessage);
} // end-while
// Check if no messages were collected, just return nothing
if (0 == messageInterchange.Count)
return null;
} // end-if
// Check if all collected messages are returned
if (currentMessage == messageInterchange.Count)
return null;
// Return the current collected message
return (IBaseMessage)messageInterchange[currentMessage++];
} // end-method GetNext()
#endregion
private ArrayList messageInterchange = null;
private int currentMessage = 0;
}
}