【问题标题】:Split file by keyword按关键字拆分文件
【发布时间】:2021-04-17 21:56:52
【问题描述】:

在我的工作中,我们使用 EDI UNIFACT,我正在尝试导入这些消息。 我正在使用一个接受文件(streamreader)并映射信息的开源库,问题是我收到的一些文件没有这个库的正确格式。

每条消息从 UNB ... 开始,在 UNZ ...结束。

UNB+UNOA:2+
UNH+1+CODECO
.........
UNT+19+1'
UNZ+1+144427'
------------------> I need to separate here 
UNB+UNOA:2+
UNH+1+CODECO
.......
UNT+19+1'
UNZ+1+144427'
.....

我已经使用流式阅读器搜索单词,然后重置它。

foreach (string filename in Directory.GetFiles(path))
{
  using (var stream = new StreamReader(filename))
  {
    while (!stream.EndOfStream)
    {
      var line = stream.ReadLine();
      if (line.Contains(@"CODECO")) //Codeco
      {
        stream.DiscardBufferedData();
        stream.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
        var grammar_read = EdiGrammar.NewEdiFact();
        var interchange = default(Interchange<CODECO_D95B>);
        interchange = new EdiSerializer().Deserialize<Interchange<CODECO_D95B>>(stream, grammar_read);
        if (interchange != null)
          list.AddRange(ImportCODECO(interchange));               
       }
    }
 }             

我的问题是,拆分这些文件,以便我可以分别输入来自文件的每个块的信息?

非常感谢

【问题讨论】:

  • 这是一种特殊的格式,你通常会使用特殊的解析器来解析它。有一些漂浮在附近
  • 我有一个解析器,如果它只在 UNB 和 UNZ 之间工作,这就是为什么我需要将每个文件拆分为多个文件的原因。或者理想情况下重新使用流阅读器并逐块提供它......
  • 使用FIle.ReadLines,然后使用扩展方法(我的是GroupByWhile)或使用计数器和常规GroupBy将行分组为块。

标签: c# streamreader edi


【解决方案1】:

要分离和收集您需要创建一个开始状态和结束状态之间的内容,每个开始结束周期都会重置。在每个周期中,您都会在 StringBuilder 中收集数据并收集到一个列表中。

我已经制定了一个概念性可行的解决方案,我很确定以后可以对其进行优化。

为此,我创建了如下输入:

UNB+UNOA:2+
UNH+1+CODECO
My text1 chunk1
My text2 chunk1
My text3 chunk1
UNT+19+1'
UNZ+1+144427'
UNB+UNOA:2+
UNH+1+CODECO
My text1 chunk2
My text2 chunk2
My text3 chunk2
UNT+19+1'
UNZ+1+144427'

所以我将第一个和第二个分开并收集它们之间的块数据。

string startSyntax1 = "UNB+UNOA:2+";
string startSyntax2 = "UNH+1+CODECO";
string endSyntax1 = "UNT+19+1'";
string endSyntax2 = "UNZ+1+144427'";
List<string> chunks = new List<string>();
bool startState = false;
bool endState = false;
StringBuilder sb = null;

foreach (var s in lines)
{
    if (s.StartsWith(startSyntax1) && !startState)
    {
        sb = new StringBuilder();
        startState = true;
    }

    if (startState)
    {
        if (!startSyntax1.StartsWith(s) && !startSyntax2.StartsWith(s) && !endSyntax1.StartsWith(s) && !endSyntax2.StartsWith(s))
        {
            sb.Append($"{s}{Environment.NewLine}");
        }
        endState = s.StartsWith(endSyntax2);
    }

    if (startState && endState)
    {
        var text = sb.ToString();
        chunks.Add(text);
        startState = false;
        endState = false;
    }
}

如果我们现在打印列表,我们会得到以下输出:

My text1 chunk1
My text2 chunk1
My text3 chunk1

My text1 chunk2
My text2 chunk2
My text3 chunk2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多