[英]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.