字符串生成器和字符串大小
String Builder and string size
为什么 StringBuilder 的大小大于字符串(~250MB)。
请阅读问题。我想知道字符串中大小限制的原因,但不是在 stringbuilder 中。我已经解决了读取文件的问题。
是的,我知道有一些操作,我们可以在字符串生成器上执行附加、替换、删除等操作。但是当我们无法从中获取 ToString() 并且我们不能'不要直接写在文件里。我们必须让 ToString() 实际使用它,但是因为它的大小超出了字符串范围,所以它抛出了异常。
所以特别是当我将大约 1 GB 的文件读入字符串生成器但无法将其放入字符串时,是否使用了任何大小大于字符串的字符串生成器。我通过 String 阅读了 StringBuilder 的所有优点和缺点,但我无法解释这个
更新:
我想从文件中加载 XMLDocument,如果读取块则无法加载数据,因为根级节点需要其结束标记,该标记将位于其他块块中
更新:
我知道这不是一个正确的方法现在我是不同的过程但我仍然想知道字符串中大小限制的原因而不是 stringbuilder
更新:
我已经解决了我的问题,想知道 stringbuilder 没有内存限制的原因。
您可以使用 StringBuilder.ToString(int, int)
从 StringBuilder 获取大量内容的 较小块。
此外,您可能需要考虑是否真的使用了正确的工具来完成工作。 StringBuilder 的目的是构建和修改字符串,而不是将大文件加载到内存中。
Why StringBuilder Size is greater than string(~250MB).
原因取决于 .net 的版本。
Eric Lippert 在这里提到了两个实现:
字符串生成器在内部维护 char[]
。当您附加时,它可能必须调整此数组的大小。为了停止每次追加时都需要调整它的大小,它会调整到更大的大小以预测未来的追加(实际上它的大小加倍)。所以 StringBuilder
最终通常比它的内容大,大小是原来的两倍。
较新的实现维护了 char[]
的链表。如果你做了很多小的附加,链表的开销可能会占额外的 250MB。
在正常使用中,考虑到性能优势,字符串的额外 100% 大小暂时不会产生一点差异,但是当您处理 GB 时,它变得很重要,这不是它的预期用途.
为什么你得到 OutOfMemoryException
链表实现比 string
更适合内存,因为它不需要一个连续的 1GB 块。当您 ToString
时,它会强制它尝试找到 另一个 GB,这也是连续的,这就是问题所在。
为什么没有约束来阻止这种情况?
好吧。约束是如果在 ToString
期间没有足够的内存来创建 string
,则抛出 OutOfMemoryException
.
您可能希望在 Append
操作期间发生这种情况,但这无法确定。 StringBuilder
可以查看空闲内存,但在您调用 ToString
之前这可能会发生变化。所以 StringBuilder
的作者可以设置一个任意的限制,但这不能同样适用于所有系统,因为有些系统比其他系统有更多的内存。
您可能还想在调用 ToString
之前执行减小 StringBuilder
大小的操作,或者根本不调用 ToString
!因此,仅仅因为 StringBuilder
太大而无法 ToString
在任何时候都不是抛出异常的理由。
您可以尝试以下方法来处理大型 XML 文件。
CodeProject
为什么 StringBuilder 的大小大于字符串(~250MB)。
请阅读问题。我想知道字符串中大小限制的原因,但不是在 stringbuilder 中。我已经解决了读取文件的问题。
是的,我知道有一些操作,我们可以在字符串生成器上执行附加、替换、删除等操作。但是当我们无法从中获取 ToString() 并且我们不能'不要直接写在文件里。我们必须让 ToString() 实际使用它,但是因为它的大小超出了字符串范围,所以它抛出了异常。
所以特别是当我将大约 1 GB 的文件读入字符串生成器但无法将其放入字符串时,是否使用了任何大小大于字符串的字符串生成器。我通过 String 阅读了 StringBuilder 的所有优点和缺点,但我无法解释这个
更新: 我想从文件中加载 XMLDocument,如果读取块则无法加载数据,因为根级节点需要其结束标记,该标记将位于其他块块中
更新: 我知道这不是一个正确的方法现在我是不同的过程但我仍然想知道字符串中大小限制的原因而不是 stringbuilder
更新: 我已经解决了我的问题,想知道 stringbuilder 没有内存限制的原因。
您可以使用 StringBuilder.ToString(int, int)
从 StringBuilder 获取大量内容的 较小块。
此外,您可能需要考虑是否真的使用了正确的工具来完成工作。 StringBuilder 的目的是构建和修改字符串,而不是将大文件加载到内存中。
Why StringBuilder Size is greater than string(~250MB).
原因取决于 .net 的版本。
Eric Lippert 在这里提到了两个实现:
字符串生成器在内部维护 char[]
。当您附加时,它可能必须调整此数组的大小。为了停止每次追加时都需要调整它的大小,它会调整到更大的大小以预测未来的追加(实际上它的大小加倍)。所以 StringBuilder
最终通常比它的内容大,大小是原来的两倍。
较新的实现维护了 char[]
的链表。如果你做了很多小的附加,链表的开销可能会占额外的 250MB。
在正常使用中,考虑到性能优势,字符串的额外 100% 大小暂时不会产生一点差异,但是当您处理 GB 时,它变得很重要,这不是它的预期用途.
为什么你得到 OutOfMemoryException
链表实现比 string
更适合内存,因为它不需要一个连续的 1GB 块。当您 ToString
时,它会强制它尝试找到 另一个 GB,这也是连续的,这就是问题所在。
为什么没有约束来阻止这种情况?
好吧。约束是如果在 ToString
期间没有足够的内存来创建 string
,则抛出 OutOfMemoryException
.
您可能希望在 Append
操作期间发生这种情况,但这无法确定。 StringBuilder
可以查看空闲内存,但在您调用 ToString
之前这可能会发生变化。所以 StringBuilder
的作者可以设置一个任意的限制,但这不能同样适用于所有系统,因为有些系统比其他系统有更多的内存。
您可能还想在调用 ToString
之前执行减小 StringBuilder
大小的操作,或者根本不调用 ToString
!因此,仅仅因为 StringBuilder
太大而无法 ToString
在任何时候都不是抛出异常的理由。
您可以尝试以下方法来处理大型 XML 文件。 CodeProject