在C#中,我正在尝试为StringBuilder构建一个名为AppendCollection()的扩展方法,它可以让我这样做:
var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
var people = new List<Person>() { ...init people here... };
var orders = new List<Orders>() { ...init orders here... };
sb1.AppendCollection(people, p => p.ToString());
sb2.AppendCollection(orders, o => o.ToString());
string stringPeople = sb1.ToString();
string stringOrders = sb2.ToString();
Run Code Online (Sandbox Code Playgroud)
stringPeople最终会为列表中的每个人添加一行.每一行都是p.ToString()的结果.同样对于stringOrders.我不太清楚如何编写代码来使lambdas与泛型一起工作.
我正在编写RenderContents()ASP.NET服务器控件的方法.该方法使用HtmlTextWriter对象来呈现输出内容.对于我正在编写的控件,使用这些HtmlTextWriter方法似乎需要很多行代码来打开和关闭每个标记并将每个属性添加到流中.最后,我觉得我最终会得到比它需要的时间长得多的代码.
我在想,如果我使用了一个可链接的类StringBuilder,我的代码会更清晰,更容易编写.
我想知道的是,有没有理由使用该HtmlTextWriter对象来呈现我的整个控件的内容?除了安全检查(我假设),它包括确保您不以错误的顺序写标签或创建无效标记,我没有看到原因.
看起来像这样做会更容易:
protected override void RenderContents(HtmlTextWriter output)
{
StringBuilder s = new StringBuilder();
s.Append("lots")
.Append("of")
.Append("strings");
output.BeginRender();
output.Write(s.ToString());
output.EndRender();
}
Run Code Online (Sandbox Code Playgroud)
有什么理由说这是个坏主意吗?
更新
响应Mehrdad Afshari的回答:
我没有考虑StringBuilder实例化单独对象的内存要求.如何为HtmlTextWriter创建一个包装器,以便它可以被链接,以便不会产生额外的字符串.
public class ChainedHtmlTextWriter
{
private HtmlTextWriter _W;
public ChainedHtmlTextWriter(HtmlTextWriter writer)
{
_W = writer;
}
public ChainedHtmlTextWriter Write<T>(T value)
{
_W.Write(value);
return this;
}
public ChainedHtmlTextWriter WriteLine<T>(T value)
{
_W.WriteLine(value);
return this;
}
}
Run Code Online (Sandbox Code Playgroud) asp.net stringbuilder servercontrols htmltextwriter method-chaining
当我有StringBuilder一个容量为5 的空,我写"你好,世界!" 对它来说,C#标准是否指定了新的容量StringBuilder?我有一个模糊的记忆,它是新字符串长度的两倍(以避免每个新附加的字符串改变容量).
有什么办法可以克隆StringBuilder吗?我正在按位读取文件,然后将这些位转换为ASCII字符,之后我将字符集收集到字符串构建器中,当我有8个字符时,我将字符串生成器对象放入数组列表中.然后我清理它并再次做同样的事情.但是由于内存而无法创建新的字符串构建器,因此无法对该"字符串"构建器进行更改,因为在"阵列列表"中也会更改该构建器.
所以我想我必须克隆String Builder并将其放入Array List.只有一个问题String Builder没有clone().那么我的替代方案是什么?
考虑到性能和内存,也许有人可以提供一些简洁的方法来做这件事.
ArrayList characters = new ArrayList(); int counter = 0;
StringBuilder sb = new StringBuilder(blockSize-1);
while (mbb.hasRemaining()) {
char charAscii = (char)mbb.get();
counter++;
charCounter++;
if (counter == blockSize){
sb.append(charAscii);
characters.add(sb);//sb.toString()
sb.delete(0, sb.length());
counter = 0;
}else{
sb.append(charAscii);
}
if(!mbb.hasRemaining()){
characters.add(sb);
}
}
fc.close();
return characters;
Run Code Online (Sandbox Code Playgroud) 我有一个.NET 4 WCF服务,它向客户端发送一些由客户端反序列化的大对象(~115Mb).对象第一次进入时反序列化很好.但是,所有后续调用都会抛出一个OutOfMemoryException.我已经检查过以确保我所有人IDisposables都被包裹起来using.我查看了与此类似的其他问题,例如BinaryFormatter outofmemory异常反序列化
和来自MemoryStream的Deserialize在C#中抛出OutOfMemory异常
.我尝试了一些人们推荐的解决方案,包括使用Simon Hewitt的Optimized Serializer.但是,最后,他仍然依赖于BinaryFormatter反序列化对象.
我抓住了OutOfMemoryException并查看了堆栈跟踪(见下文).跟踪似乎源于StringBuilder类中内存利用率的问题.我读过其他文章,关于如何StringBuilder在需要更多空间时使用(长度*2)算法导致内存问题.
at System.Text.StringBuilder.ToString()
at System.IO.BinaryReader.ReadString()
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectString(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
Run Code Online (Sandbox Code Playgroud)
有没有办法以BinaryFormatter不同的方式工作而不使用StringBuilder或是否有更好的替代方案来BinaryFormatter更好地管理内存?
c# stringbuilder out-of-memory binaryformatter deserialization
我正在读一本名为.NET Gotchas的书(值得一读IMO),它说明了String和StringBuilder之间的性能差异,并提出了一个我觉得无法回答的问题!虽然我不知道任何一个类的内部(没有看这些类的反映版本),但我想知道; 因为.NET中的运算符是可重载的,为什么Microsoft没有实现String类在内部使用StringBuilder并重载连接运算符以简单地在StringBuilder中调用.Append()?我猜是有一些潜在的原因导致为什么不是这样,如果是这样,为什么呢?
我有一个记录和跟踪相关的代码,在整个代码中经常调用,特别是在打开跟踪时.StringBuilder用于构建String.字符串具有合理的最大长度,我想大约数百个字符.
问题:是否有现有的库可以执行以下操作:
// in reality, StringBuilder is final,
// would have to create delegated version instead,
// which is quite a big class because of all the append() overloads
public class SmarterBuilder extends StringBuilder {
private final AtomicInteger capRef;
SmarterBuilder(AtomicInteger capRef) {
int len = capRef.get();
// optionally save memory with expense of worst-case resizes:
// len = len * 3 / 4;
super(len);
this.capRef = capRef;
}
public syncCap() {
// call when string is fully built
int cap; …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个自定义键盘并在android SDK中使用"SoftKeyboard"示例.我对该示例进行了少量修改并创建了我的自定义键盘.我可以将此自定义键盘与我的Android设备的默认消息应用程序一起使用.
现在,我想单击自定义键盘中的按钮,并在键入SMS时添加图像.我注意到String Builder在"SoftKeyBoard.java" class(private StringBuilder mComposing = new StringBuilder())中,当我们使用键盘输入字母时它会附加字符.
我试图在下面添加我的SD卡图像,
String imageDataString = "";
String path = Environment.getExternalStorageDirectory().toString() + "/SamplePictures/";
File file = new File(path, "myimage.jpg");
try {
FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int) file.length()];
imageInFile.read(imageData);
// Converting Image byte array into Base64 String
imageDataString = encodeImage(imageData);
imageInFile.close();
} catch (FileNotFoundException e) {
System.out.println("Image not found" + e);
} catch (IOException ioe) {
System.out.println("Exception while reading the Image …Run Code Online (Sandbox Code Playgroud) {
StringBuilder fileBuff = new StringBuilder();
long before = getUsedMem();
try {
//Open InputStreamReader here
while ((currLine = lnr.readLine()) != null) {
fileBuff.append("\r\n" + currLine);
}
//Close streams
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("usedTotal: " + (getUsedMem() - before));
}
private long getUsedMem() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
Run Code Online (Sandbox Code Playgroud)
在运行代码几次的时候,我得到了usedTotal ~ 14279888,但如果我用我替换fileBuff.append("\r\n").append(currLine)得到几乎双倍的内存~ 33264440.
有人可以解释原因,因为我知道String串联也使用StringBuilder?
我:fileBuff.append("\ r \n"+ currLine);
62: aload 6
64: invokevirtual #16 // Method java/io/LineNumberReader.readLine:()Ljava/lang/String;
67: dup …Run Code Online (Sandbox Code Playgroud) 我得到了以下代码,我被问到哪个选项获得以下模式:
XXXX-XXXX-XXXX-2324
...
代码如下:
public class CCMark {
public static String maskCC(String creditCard){
String x = "XXXX-XXXX-XXXX-";
//line 1
}
public static void main(String[] args) {
System.out.println(maskCC("1234-5678-1234-2324"));
System.out.println(maskCC("4567-5678-1234-5643"));
System.out.println(maskCC("1234-5678-1234-4654"));
System.out.println(maskCC("4567-5678-1234-5435"));
}
}
Run Code Online (Sandbox Code Playgroud)
下面可以插入"第1行"的可能选项:
A)
return x + creditCard.substring(15, 19);
B)
StringBuilder sb = new StringBuilder(x);
sb.append(creditCard, 15, 19);
return sb.toString();
Run Code Online (Sandbox Code Playgroud)
我认为这里最好的选择,因为A和B为我们提供了相同的输出,是B,因为它使用的是StringBuilder,这意味着它的方法是可变的,因此它将使用比选项A更少的内存.
我错了吗?可能是这种特殊情况的选项A是最好的选择吗?