首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >解析具有不同大小字段的表示“定长”消息的C#字符串

解析具有不同大小字段的表示“定长”消息的C#字符串
EN

Stack Overflow用户
提问于 2019-02-16 08:15:51
回答 2查看 859关注 0票数 -1

我在中有一个固定长度的字符串消息,如下所示:

代码语言:javascript
复制
"\0\0\0j\0\0\0\vT3A1111        2999BOSH                          2100021        399APV                           2100022  "

这条消息是我通过将byte[]读入StringBuilder来构建字符串而创建的。

上面,字符串部分"\0\0\0j\0\0\0\v“被认为是长度和ID字段,都是4字节长。但是,我不确定如何提取这两个值,但我可以看到HEX 0j是106 (1+1+8+9+30+9+9+30+9=106总长度)。我不确定为什么上面的"v“不是"0v”,但我知道它应该是代表消息id的十六进制值。

长度为4的前两个字段是十六进制,其他所有字段都是ASCII。

这不是EDI消息(因此不能使用EDI解析器库),并且与具有某种字段标识符的EDI消息不同,我只有字节流,并且我只知道字段的长度。这些字段包括:

代码语言:javascript
复制
4  byte long message length      ("\0\0\0j")
4  byte long message id          ("\0\0\0\v")
1  byte long message type        ("T")
1  byte long message sequence    ("3")
8  byte long car Id              ("A1111   ")  
9  byte long part-1 price        ("     2999")
30 byte long part-1 manufacturer ("BOSH                          ")
9  byte long part#               ("2100021  ")
9  byte long part-2 price        ("      399")
30 byte long part-2 manufacturer ("APV                           ")
9  byte long part#               ("2100022  ")

所以,上面我有两个制造商制造的两个零件,但在真实的例子中,它可以是更多的零件,而不仅仅是两个:

代码语言:javascript
复制
Part 1, 29.99, made by Bosh, part# 2100021
Part 2, 3.99, made by APV, part# 2100022

我想把这个平面文件字符串中的所有价格和制造商字段放到一个列表对象中,其中Part是

代码语言:javascript
复制
class Part
{
   public decimal Price {get; set}
   public string Manufacturer {get; set;}
   public string PartNumber {get; set;}
}

因此,我的列表将包含所有零件及其价格和制造商。

因为我有每个字段的长度,所以我知道我可以遍历这个字符串,并获得与部分相关的数据。但是,我想知道是否有更优雅和更容易的方法来做到这一点。

或者更好的是,有没有一个开源库可以让我解析这样的东西?

我使用此方法接收此消息

代码语言:javascript
复制
private TcpClient clientSocket;
private NetworkStream serverStream;

private async System.Threading.Tasks.Task ReadResponseAsync()
{
    if (serverStream.CanRead)
    {
        byte[] readBuffer = new byte[1024];
        StringBuilder receivedMessage = new StringBuilder();
        int readSoFar = 0;

        do
        {
            readSoFar = await serverStream.ReadAsync(readBuffer, 0, readBuffer.Length);
            receivedMessage.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, readSoFar));
        } 
        while (serverStream.DataAvailable);

        string msg = receivedMessage.ToString();
    }
    else
    {
        Log("Error", "Cannot read from NetworkStream");
    }
}

我试着把你的答案贴出来,然后在LinqPad中运行(从来没有用过,只是下载并安装了它),但我看不到你在答案中贴出的表格结构。你是怎么做到的?

以下是我得到的结果

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-16 08:58:48

你说"byte[] into a StringBuilder to build string",所以我认为你有一个字符串。也许可以尝试使用SubString(..),如下所示:

代码语言:javascript
复制
var length = int.Parse(message.SubString(0,4);
var id = int.Parse(message.SubString(4,4);

编辑:如果有不需要的填充字符,请尝试

代码语言:javascript
复制
message.Replace('-', ' ');

不是很优雅,但它会工作的。

票数 0
EN

Stack Overflow用户

发布于 2019-02-16 09:07:31

也许可以尝试一下这样的方法:

代码语言:javascript
复制
void Main()
{
    var line = "00580011T3A1111        2999Bosh                                399APV                                2399MAG                           ";

    var lengths = new[] { 4, 4, 1, 1, 8, 9, 30, 9, 30, 9, 30 };
    var starts = lengths.Aggregate(new[] { 0 }.ToList(), (a, x) => { a.Add(a.Last() + x); return a; });

    var fields = starts.Zip(lengths, (p, l) => line.Substring(p, l).Trim()).ToArray();

    var message = new
    {
        message_length = int.Parse(fields[0]),
        message_id = int.Parse(fields[1]),
        message_type = fields[2],
        message_sequence = int.Parse(fields[3]),
        car_Id = fields[4],
        parts =
            Enumerable
                .Range(0, 3)
                .Select(x => x * 2 + 5)
                .Select(x => new Part
                {
                    Price = decimal.Parse(fields[x]),
                    Manufacturer = fields[x + 1]
                }).ToArray(),
    };
}

public class Part
{
    public decimal Price { get; set; }
    public string Manufacturer { get; set; }
}

对于我使用的样本数据(我必须修复它,因为在您的问题中,即使当我删除|并将-替换为空格时,它似乎也是损坏的),我得到了以下结果:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54718631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档