将int作为文本流式传输到文件中而不创建字符串对象

时间:2017-05-18 21:16:06

标签: c# memory-management garbage-collection

我正在将一些文本流式传输到文件中。以下代码是用于演示此问题的MCVE:

using (var fileStream = File.OpenWrite(@"d:\test.txt"))
{
    using (var streamWriter = new StreamWriter(fileStream))
    {
        for (int i = 0; i < 20000000; i++)
        {
            streamWriter.Write("Just ");
            streamWriter.Write(i);
            streamWriter.Write(" example.\r\n");
        }
    }
}

正如您所看到的,它不仅将字符串流式传输到文件中,还将其整合到内部。

不幸的是,Write(int)方法似乎在数字上调用ToString(),因此上面的代码创建了20M字符串对象。这可以通过像dotMemory这样的内存分析器来证明。这些字符串将被垃圾收集,但它们会在垃圾收集器上产生577 MB的吞吐量。

有没有办法直接将int(以人类可读的格式,而不是二进制格式)流入文件而不创建临时字符串?

1 个答案:

答案 0 :(得分:2)

您可以使用递归一次一位地执行此操作:

void writeInt(StreamWriter w, int i)
{
    if (i<0)
    {
        w.Write('-');
        writeInt(w, -i);
    }
    else if (i>=10)
    {
        writeInt(w, i/10); // Write all but the last digit
        w.Write((char)('0' + i%10)); // Write the last digit
    }
    else
    {
        w.Write((char)('0' + i)); // Write single digit number
    }
}

对于给定的整数,请调用它:

int i = 42;
streamWriter.Write("Just ");
writeInt(streamWriter, i);
streamWriter.Write(" example.\r\n");