全部,当我为固定文本文件生成单行时,我正在执行以下Append
formattedLine.Append(this.reversePadding ?
strData.PadLeft(this.maximumLength) :
strData.PadRight(this.maximumLength));
此特殊异常发生在PadLeft()
this.maximumLength = 1,073,741,823
[从SQL Server收集的NVARCHAR(MAX)
的字段长度]中。在例外时formattedLine = "101102AA-1"
,为什么会发生这种情况。我的最大允许长度应为2,147,483,647
?
我想知道https://stackoverflow.com/a/1769472/626442是否在这里作为答案 - 但是,我正在管理任何内存,并在可能的情况下对任何一次性对象和Dispose()
块进行适当的using
调用。
请注意。此固定文本导出正在后台线程上完成。
感谢您的时间。
答案 0 :(得分:3)
这个特殊异常发生在PadLeft()上,其中this.maximumLength = 1,073,741,823
右。因此,您正在尝试创建一个包含超过十亿个字符的字符串。
这不会起作用,而且非常非常怀疑这是你真正想做的事情。
请注意,.NET中的每个char
都是两个字节,而.NET中的也是字符串是以空值终止的...并且还有一些超出数据的其他字段(长度,一个)。这意味着您至少需要2147483652个字节+对象开销,这会使您超过每个对象2GB的限制。
如果你在64位版本的Windows上运行,在.NET 4.5中,有一个特殊的app.config设置<gcAllowVeryLargeObjects>
允许大于2GB的数组。但是,我不相信这会改变您的特定用例:
在应用程序配置文件中使用此元素可以启用大小超过2 GB的数组,但不会更改对象大小或数组大小的其他限制:
数组中的最大元素数是UInt32MaxValue。
对于字节数组和单字节结构数组,任何单个维度的最大索引为2,147,483,591(0x7FFFFFC7),其他类型为2,146,435,071(0X7FEFFFFF)。
字符串和其他非数组对象的最大大小不变。
无论如何,你想在创建它后用这个字符串做什么?
答案 1 :(得分:2)
为了为此操作分配内存,操作系统必须找到足够大的连续内存来执行操作。
内存碎片可能导致这种情况无法实现,尤其是在使用32位.NET实现时。
答案 2 :(得分:1)
我认为可能有更好的方法来实现您想要实现的目标。据推测,这个StringBuilder
将被写入文件(这就像你的描述中所说的那样),显然,你也可能处理大型(巨大的)数据库记录。
你可能会考虑一种流媒体方法,它不需要分配如此庞大的内存块。 为此,您可以调查以下内容:
SqlDataReader
类公开了GetChars()
方法,允许您读取单个大型记录的大块。
然后,不是使用StringBuilder
,而是使用StreamWriter
(或其他TextWriter
派生类)将每个块写入输出。
这只需要在应用程序的内存空间中一次填充一个缓冲区。祝你好运!