我使用下面的代码来分割字符串,但这需要很多时间。
using (StreamReader srSegmentData = new StreamReader(fileNamePath))
{
string strSegmentData = "";
string line = srSegmentData.ReadToEnd();
int startPos = 0;
ArrayList alSegments = new ArrayList();
while (startPos < line.Length && (line.Length - startPos) >= segmentSize)
{
strSegmentData = strSegmentData + line.Substring(startPos, segmentSize) + Environment.NewLine;
alSegments.Add(line.Substring(startPos, segmentSize) + Environment.NewLine);
startPos = startPos + segmentSize;
}
}
请建议我一种将字符串分割成固定大小的较小块的替代方法
首先你应该定义你的意思块大小。如果你的意思是具有固定数量的块代码单元那么你的实际算法可能很慢但它有效。如果这不是你的意图和你真正的意思具有固定数量的块人物然后它就坏了。我在这篇代码审查帖子中讨论了类似的问题:将字符串分割成相同长度的块 https://codereview.stackexchange.com/q/111919/13424那么我在这里只重复相关部分。
一种提议的(且未经测试的)实现可能是这样的:
public static IEnumerable<string> Split(this string value, int desiredLength)
{
var characters = StringInfo.GetTextElementEnumerator(value);
while (characters.MoveNext())
yield return String.Concat(Take(characters, desiredLength));
}
private static IEnumerable<string> Take(TextElementEnumerator enumerator, int count)
{
for (int i = 0; i < count; ++i)
{
yield return (string)enumerator.Current;
if (!enumerator.MoveNext())
yield break;
}
}
它没有针对速度进行优化(正如您所看到的,我尝试使用枚举来保持代码简短明了),但是对于大文件,它的性能仍然比您的实现更好(原因请参阅下一段)。
关于您的代码请注意:
- 你正在建造一个巨大的
ArrayList
(?!) 保存结果。另请注意,通过这种方式您可以调整大小ArrayList
多次(即使给定输入大小和块大小,然后其最终大小已知)。
-
strSegmentData
被重建多次,如果需要积累字符则必须使用StringBuilder
否则每个操作都会分配一个新字符串并复制旧值(这很慢并且还会增加垃圾收集器的压力)。
有更快的实现(请参阅链接的代码审查帖子,特别是Heslacher 的实现 https://codereview.stackexchange.com/a/112018/13424以获得更快的版本)并且如果您不需要正确处理 Unicode(您是sure你只管理 US ASCII 字符)那么还有一个漂亮的Jon Skeet 的可读实现 https://stackoverflow.com/a/1632109/1207195(请注意,在对代码进行分析后,您仍然可以通过预分配正确大小的输出列表来提高大文件的性能)。我不会在这里重复他们的代码,请参阅链接的帖子。
在你的具体您不需要读取内存中的整个大文件,你可以读取/解析n一次字符(不必太担心磁盘访问,I/O 已缓冲)。它会稍微降低性能,但会大大提高内存使用率。或者,您可以逐行读取(设法处理跨行块)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)