我已经将一个流下载为一个大约36MB的byte []'raw'。然后我将其转换为带有
的字符串string temp = System.Text.Encoding.UTF8.GetString(raw)
然后我需要用“\ r \ n”替换所有“\ n”,所以我试过
string temp2 = temp.Replace("\n","\r\n")
但它引发了“Out of Memory”异常。然后我尝试使用StringBuilder创建一个新字符串:
string temp2 = new StringBuilder(temp).Replace("\n","\r\n").toString()
并没有抛出异常。为什么首先会出现内存问题(我这里只处理36MB),还有为什么StringBuilder.Replace()在另一个没有的情况下工作?
答案 0 :(得分:6)
使用时:
string temp2 = temp.Replace("\n","\r\n")
对于字符串temp中“/ n”的每个匹配,系统会使用替换创建一个新字符串。
使用StringBuilder不会发生这种情况,因为StringBuilder是可变的,因此您实际上可以修改同一个对象而无需创建另一个对象。
示例:强>
temp = "test1\ntest2\ntest3\n"
使用第一种方法(字符串)
string temp2 = temp.Replace("\n","\r\n")
相当于
string aux1 = "test1\r\ntest2\ntest3\n"
string aux2 = "test1\r\ntest2\r\ntest3\n"
string temp2 = "test1\r\ntest2\r\ntest3\r\n"
使用Secon方法(StringBuilder)
string temp2 = new StringBuilder(temp).Replace("\n","\r\n").toString()
相当于
Stringbuilder aux = "test1\ntest2\ntest3\n"
aux = "test1\r\ntest2\ntest3\n"
aux = "test1\r\ntest2\r\ntest3\n"
aux = "test1\r\ntest2\r\ntest3\r\n"
string temp2 = aux.toString()
答案 1 :(得分:3)
来自MSDN的StringBuilder:
修改此类实例的大多数方法都返回一个 引用同一个实例,您可以调用方法或属性 在参考上。如果你想写一个单一的话,这很方便 链接连续操作的声明。
因此,当您使用String调用replace时,将分配新对象(大数据 - 36MB)以创建新字符串。但是StringBuilder访问相同的实例对象并且不会创建新的实例对象。
答案 2 :(得分:1)
存在内存压力的概念,这意味着创建的临时对象越多,垃圾收集运行的频率就越高。
所以: StringBuilder创建的临时对象更少,内存压力也更小。
替换
我们接下来使用StringBuilder来替换循环中的字符。首先将字符串转换为StringBuilder,然后调用StringBuilder的方法。这更快 - StringBuilder类型在内部使用字符数组
答案 3 :(得分:0)
字符串在C#中是不可变的。如果使用string.replace()方法,系统将为每个替换创建一个String对象。 StringBuilder类将帮助您避免对象创建。