字符串生成器和字符串大小

时间:2015-05-05 07:37:44

标签: c# string memory stringbuilder

为什么StringBuilder的大小大于字符串(~250MB)。

请阅读问题。我想知道字符串中大小约束的原因,但不知道在stringbuilder中。我已经解决了阅读文件的问题。

是的,我知道有操作,我们可以对字符串构建器执行如append,replace,remove等。但是当我们无法从它获取ToString()并且我们无法写入时它的用途是什么它直接在文件中。我们必须让ToString()实际使用它,但由于它的大小超出字符串范围,因此抛出异常。

所以特别是使用字符串构建器,其大小比字符串大,因为我将大约1 GB的文件读入字符串构建器但不能将其转换为字符串。我在String上阅读了StringBuilder的所有优点和缺点,但我无法解释这个

更新 我想从文件加载XMLDocument,如果读入块,则无法加载数据,因为根级节点需要其关闭标记,这将在其他块块中

更新 我知道这不是一个正确的方法现在我是不同的过程,但我仍然想知道字符串大小约束的原因,但不是在stringbuilder中

更新 我修复了我的问题,想知道stringbuilder上没有内存约束的原因。

3 个答案:

答案 0 :(得分:5)

您可以使用StringBuilder.ToString(int, int)从StringBuilder中获取大量内容的较小的块

此外,您可能想要考虑是否真的使用正确的工具来完成工作。 StringBuilder的目的是构建和修改字符串,而不是将大文件加载到内存中。

答案 1 :(得分:5)

  

为什么StringBuilder的大小大于字符串(~250MB)。

原因取决于.net。

的版本

Eric Lippert在这里提到了两个实现:https://stackoverflow.com/a/6524401/360211

字符串构建器内部维护char[]。附加时可能需要调整此数组的大小。为了阻止它每次附加时需要调整大小,它会调整大小以预测未来的附加(实际上它的大小翻倍)。因此,StringBuilder通常会比其内容更大,也就是大小的两倍。

较新的实现维护char[]的链接列表。如果你做了很多小的追加,链表的开销可能会增加250MB。

在正常使用中,在字符串上额外100%的大小暂时不会产生一点差别,因为性能优势,但是当你处理GB时,它变得很重要,这不是它的预期用途

为什么得到OutOfMemoryException

链接列表实现可以比string更适合内存,因为它不需要一个1GB的连续块。当你ToString时,它会强制它尝试找到另一个 GB,这也是连续的,这就是问题所在。

为什么没有约束阻止这个?

嗯有。约束条件是如果在string期间没有足够的内存来创建ToString,则抛出OutOfMemoryException

您可能希望在Append操作期间发生这种情况,但这是无法确定的。 StringBuilder可以查看可用内存,但在调用ToString之前可能会更改。因此StringBuilder的作者可以设置一个任意限制,但这并不适合所有系统,因为有些内存比其他系统更多。

您还可能希望在调用StringBuilder之前执行减少ToString大小的操作,或者根本不调用ToString!因为StringBuilder在任何时候都太大而不能ToString,这不是抛出异常的理由。

答案 2 :(得分:0)

您可以尝试以下方法来处理大型XML文件。 CodeProject