C# C字符串(和其他.NET API)的大小是否限制为2GB?
今天我注意到C#的String类将字符串的长度作为Int返回。由于Int总是32位,无论采用何种体系结构,这是否意味着字符串的长度只能为2GB或更短 2GB的字符串将是非常不寻常的,并且会带来许多问题。然而,大多数.NETAPI似乎使用“int”来传递长度和计数等值。这是否意味着我们永远只限于适合32位的集合大小C# C字符串(和其他.NET API)的大小是否限制为2GB?,c#,.net,visual-studio,string,C#,.net,Visual Studio,String,今天我注意到C#的String类将字符串的长度作为Int返回。由于Int总是32位,无论采用何种体系结构,这是否意味着字符串的长度只能为2GB或更短 2GB的字符串将是非常不寻常的,并且会带来许多问题。然而,大多数.NETAPI似乎使用“int”来传递长度和计数等值。这是否意味着我们永远只限于适合32位的集合大小 似乎是.NETAPI的一个根本问题。我希望通过“size\t”的等价项返回count和length等内容。正确,最大长度是Int32的大小,但是如果处理的字符串大于此值,则可能会遇到其
似乎是.NETAPI的一个根本问题。我希望通过“size\t”的等价项返回count和length等内容。正确,最大长度是Int32的大小,但是如果处理的字符串大于此值,则可能会遇到其他内存问题 似乎是一个基本的问题 NET API 我不知道我是否会走那么远 考虑一下.NET中几乎所有的集合类。很可能它有一个
Count
属性,返回一个int
。因此,这表明该类的大小为int.MaxValue
(2147483647)。这不是一个真正的问题;这是一个限制——在绝大多数情况下,这是一个完全合理的限制
无论如何,另一种选择是什么?有uint
——但这不符合CLS。然后是long
如果Length
返回了long
,该怎么办
// Lord knows how many characters
string ulysses = GetUlyssesText();
// allocate an entirely new string of roughly equivalent size
string schmulysses = ulysses.Replace("Ulysses", "Schmulysses");
public static string BigStringIndex(this string s)
{
return String.Concat(s[0], s[1]);
}
bigStringContainer[item.BigStringIndex()].Add(item);
基本上,如果您将
string
视为一种用于存储无限量文本的数据结构,那么您就有了不切实际的期望。对于这种大小的对象,您是否需要将它们保存在内存中(与硬盘相反)就成了问题。字符串的某个值。长度()大约为5MB使用字符串已经不太实际了。字符串针对短文本位进行了优化
想想当你这样做的时候会发生什么
msString += " more chars"
比如:
系统计算myString的长度加上“更多字符”的长度
系统分配那个数量的内存
系统将myString复制到新的内存位置
在上次复制myString字符后,系统将“更多字符”复制到新的内存位置
最初的myString由垃圾收集器来处理
虽然这对于小文本位来说很好,但对于大字符串来说却是一场噩梦,仅仅找到2GB的连续内存可能就是一个障碍
因此,如果您知道要处理的字符数超过了极少数MB,请使用一个*缓冲区类。即使在x64版本的Windows中,我也遇到了.Net将每个对象限制为2GB的问题
2GB对于医学图像来说非常小。2GB对于VisualStudio下载图像来说甚至很小。在一个集合中存储超过20亿个对象的可能性很小。在执行枚举和查找时,您将遭受一些相当严重的性能损失,这是集合的两个主要目的。如果您要处理这么大的数据集,几乎可以肯定的是,您可以采取其他一些方法,例如将单个集合拆分为许多较小的集合,这些集合包含您正在处理的整个数据集的一部分 嘿,等一下。。。。我们已经有了这个概念——它被称为字典 如果需要存储(例如)50亿个英语字符串,请使用以下类型:
Dictionary<string, List<string>> bigStringContainer;
然后将项目添加到bigStringContainer,如下所示:
// Lord knows how many characters
string ulysses = GetUlyssesText();
// allocate an entirely new string of roughly equivalent size
string schmulysses = ulysses.Replace("Ulysses", "Schmulysses");
public static string BigStringIndex(this string s)
{
return String.Concat(s[0], s[1]);
}
bigStringContainer[item.BigStringIndex()].Add(item);
今天到此为止。(显然有更有效的方法可以做到这一点,但这只是一个例子)
哦,如果你真的需要能够通过绝对索引查找任意对象,那么使用
数组而不是集合。好的,是的,您使用了一些类型安全性,但是如果您使用的文件是2GB,您可以使用long
索引数组元素,这意味着您可能会使用大量RAM,并且您会看到非常慢的性能
相反,对于非常大的文件,请考虑使用MyMyEclipse文件(参见:)。使用此方法,您可以处理几乎无限大小的文件,而不必将整个文件加载到内存中。
框架使用Int32
进行计数
/长度
属性、索引器等,这一事实有点令人费解。真正的问题是CLR当前的最大对象大小限制为2GB
所以一个字符串
——或者任何其他单个对象——都不能大于2GB
更改string
类型的Length
属性以返回long
、ulong
甚至biginger
都是毫无意义的,因为您的字符数无论如何都不能超过2^30个左右(最大大小为2GB,每个字符2个字节)
类似地,由于2GB的限制,只有bool[]
或byte[]
数组可以接近2^31个元素,每个元素只使用1个字节
当然,没有什么可以阻止您创建自己的复合类型来绕过2GB限制
(请注意,上述观察结果适用于Microsoft当前的实现,在未来的版本中可能会发生很大变化。我不确定Mono是否有类似的限制。)在4.5之前的.NET版本中,最大对象大小为2GB。从4.5开始,如果启用,则可以分配较大的对象。请注意,字符串的限制不受影响,但“数组”也应包括“列表”,因为列表由数组支持。如果我的答案是2GB字符串,则我