簡體   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