繁体   English   中英

C# 字符串拆分而不生成数组

[英]C# string Split without array generation

我在内存中有一个巨大的字符串(几百兆字节,我无法部分加载它),我想知道是否有一些简单的方法可以将此字符串拆分为由 Environment.NewLine 划分的行:a) 无需重复此操作内存中的结构(如果我使用 string.Split 它会复制它)b) 使用一些默认的 c# 方法/最低数量的高效(在性能方面)代码

实际上我想要一个方法,GetNextLineFromString。

您可以尝试枚举行,例如

private static IEnumerable<string> LinesFromString(string value) {
  if (string.IsNullOrEmpty(value))
    yield break;

  int last = 0;

  while (true) {
    int next = value.IndexOf(Environment.NewLine, last);

    if (next < 0) {
      yield return value.Substring(last);

      yield break;
    }

    yield return value.Substring(last, next - last);

    last = next + Environment.NewLine.Length;
  }
}

演示:

string text = string.Join(Environment.NewLine, 
  "ABC", 
  "D", 
  "", // <- Empty line
  "EF"
);

Console.Write(string.Join(";", LinesFromString(text)));

结果:

ABC;D;;EF

如果你想要第N行,你可以在 Linq 的帮助下查询text

int N = 1; // N is zero-based

string line = LinesFromString(text)
  .Skip(N - 1)
  .FirstOrDefault(); // Either Nth string or null

编辑:如果您使用.Net Core 3.1.Net Standard 2.1或更高版本,您可以尝试将长string表示为ReadOnlyMemory<char>并使用它的切片 例如

private static IEnumerable<ReadOnlyMemory<char>> LinesFromMemory(ReadOnlyMemory<char> value) {
  int last = 0;

  while (true) {
    int at = value.Span.Slice(last).IndexOf(Environment.NewLine);

    if (at < 0) {
      yield return value.Slice(last);

      yield break;
    }

    yield return value.Slice(last, at);

    last += at + Environment.NewLine.Length;
  }
} 

然后

string huge = string.Join(Environment.NewLine, 
  "ABC", 
  "D", 
  "", // <- Empty line
  "EF"
);

// Note, memory is not a string, but some kind of pointer (to huge) 
foreach (var memory in LinesFromMemory(huge.AsMemory())) {
  // Let's convert memory to string and print it out
  string st = memory.ToString();

  Console.Write(st);
  Console.Write(';'); 
}

您能否将字符串保存到临时文件中,通过StreamReader使用String.Spilt() ,然后最后删除该文件?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM