我找到了这些相关的线索,但它们没有直接回答我的问题:
BizTalk - Flat file with Header multiple records and Footer - Disassemble problem
Removing header from a flat file in BizTalk
我正在处理一个旧系统,它以非常松散的模式提供平面文件。特别是,标题由两行组成:第一行是标题,第二行是列标题。随后的所有行都是有效的记录。
问题是,当没有当天的记录时,列标题就被省略了;在这种情况下,我们有文档标题,然后是一个摘要行(供人使用),它通知读者当天没有记录。
因为同一个文件可以有如此不同的格式,所以我很难创建一个可以在平面文件接收管道中使用的头模式,这将允许我删除头信息。此外,由于标头是多行的,所以我似乎不能只使用回车分隔符。
我尝试过两种方法来解决这个问题:
然而,当我部署这些文件时,BizTalk将获取文件并处理它们,但是它实际上不会产生任何消息。这使我相信,BizTalk对待我的平面文件就好像整个文件是头文件一样,因此它没有找到任何记录。
我试图找到的解决方案是如何创建一个标头模式,使BizTalk将文件的前两行作为头,而不管它们的内容如何,并丢弃它们。这个是可能的吗?
编辑:不同文件的示例:
有记录:
2017-02-27 19:27:03
CustomerName, OrderNumber, Expedite, ItemNumber, Count
CustomerA, O196801, 0, I232, 2
CustomerA, O196801, 0, I255, 1
CustomerB, O196802, 0, I237, 1
CustomerC, O196803, 0, I214, 1
CustomerC, O196803, 0, I232, 2此文件中没有记录:
2017-02-27 19:30:22
***EOF***目前,我只能通过将标头和文档模式之间的分隔符定义为整个列标题行(即CustomerName, OrderNumber, Expedite, ItemNumber, Count{CR}{LF} )来处理带有记录的文件,但是,当它找到***EOF***而不是列头字符串时,这个标头模式对于空文件失败。
发布于 2017-02-28 14:16:54
也许有一些聪明的方法可以用平面文件模式来处理这个问题,但我想不起来。
我可能会为管道编写一个自定义的Decode组件,该组件将检查该***EOF***的消息的前几个字节--如果是,只需将流空(或者可能用预期的标头重写它)--否则,将流的位置重新设置为0并传递给它。
例如(注:未经测试,可能有效的代码):
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
if (pInMsg == null || pInMsg.BodyPart == null) return pInMsg;
var stream = pInMsg.BodyPart.GetOriginalDataStream();
if (stream == null || stream.Length == 0) return pInMsg;
if (!stream.CanSeek)
{
stream = new ReadOnlySeekableStream(stream);
pContext.ResourceTracker.AddResource(stream);
}
StreamReader reader = new StreamReader(stream);
pContext.ResourceTracker.AddResource(reader);
reader.ReadLine(); // date line
if (reader.ReadLine() == "***EOF***")
{
pInMsg.BodyPart.Data = null;
}
else
{
stream.Position = 0;
pInMsg.BodyPart.Data = stream;
}
return pInMsg;
}https://stackoverflow.com/questions/42446108
复制相似问题