如何“ToString”大量的字符数组?

时间:2012-03-01 20:44:58

标签: c#

我有以下代码:

public static void PrependEntitiesToFile(string pathToFile)
{
    char[] buffer = new char[10000];
    FileInfo file = new FileInfo(pathToFile);

    string renamedFile = file.FullName + ".orig";
    System.IO.File.Move(file.FullName, renamedFile);

    using (StreamReader sr = new StreamReader(renamedFile))
    using (StreamWriter sw = new StreamWriter(file.FullName, false))
    {
        string entityDeclaration = "foo";
        sw.Write(entityDeclaration);
        string strFileContents = string.Empty;
        int read;
        while ((read = sr.Read(buffer, 0, buffer.Length)) > 0)
        {
            for (int i = 0; i < buffer.Length; i++)
            {
                strFileContents += buffer[i].ToString();
            }
        }
        sw.Write(strFileContents, 0, strFileContents.Length);

    }

    System.IO.File.Delete(renamedFile);
}

这段代码有效,但SOOOOO SLOW因为我循环遍历buffer数组中的每个字符并ToString()。想象一下,当它摄取和复制一个823,000个字符的文件时,速度有多慢。

有没有办法将完全填充的buffer转换为字符串并立即添加它而不是循环遍历数组中的每个字符?或者,一般来说,有没有更快的方法呢?

我为这段代码感到羞耻。

7 个答案:

答案 0 :(得分:6)

实际上,这并不是为什么它如此缓慢。这很慢,因为你正在重复string concatenation and that's O(n^2)。如果您使用StringBuilder,您会看到更好的效果。你也可以只创建一个字符数组,并调用带有这样一个数组的constructor of string

但更好的是,一起跳过字符串,然后将缓冲区写到sw

答案 1 :(得分:1)

您应该将字符数组传递给string构造函数:

string strFileContents = new string(buffer);

我希望它快得多。

答案 2 :(得分:1)

不要,你这么近......我想,你可以像这样编写输出: 你似乎把它循环了两次......

using (StreamReader sr = new StreamReader(renamedFile))
using (StreamWriter sw = new StreamWriter(file.FullName, false))
{
    string entityDeclaration = "foo";
    sw.Write(entityDeclaration);
    string strFileContents = string.Empty;
    int read;
    while ((read = sr.Read(buffer, 0, buffer.Length)) > 0)
    {
        sw.Write(buffer);
    }
}

答案 3 :(得分:1)

我可以问为什么你这样做。因为看起来你的目标是将一个文件的内容移动到另一个char-by-char而不进行其他处理。在这种情况下,有更好的方法。

但即使您确实需要阅读所有内容,请查看File.ReadAllLines

答案 4 :(得分:1)

只需使用带有缓冲区,偏移量和长度的重载,并完全跳过转换。

using (StreamReader sr = new StreamReader(renamedFile))
using (StreamWriter sw = new StreamWriter(file.FullName, false))
{
    string entityDeclaration = "foo";
    sw.Write(entityDeclaration);
    string strFileContents = string.Empty;
    int read;
    while ((read = sr.Read(buffer, 0, buffer.Length)) > 0)
    {
        sw.Write( buffer, 0, read );
    }

}

答案 5 :(得分:1)

不要使用String。改为使用Stringbuilder。

在.NET中,字符串是不可变的,这意味着每次更改字符串时,它都会生成一个副本。这会随着时间的推移而减慢。

答案 6 :(得分:1)

应该能够做一个GetString()。它一次读取2048个字节进行转换。您还可以指定编码类型来处理不同的字符集。

public enum EncodingType 
{ 
    ASCII, 
    Unicode, 
    UTF7, 
    UTF8 
} 
public static string ByteArrayToString(byte[] bytes) 
{ 
    return ByteArrayToString(bytes, EncodingType.Unicode); 
} 

public static string ByteArrayToString(byte[] bytes, EncodingType encodingType) 
{ 
    System.Text.Encoding encoding=null; 
    switch (encodingType) 
    { 
    case EncodingType.ASCII: 
        encoding=new System.Text.ASCIIEncoding(); 
        break;    
    case EncodingType.Unicode: 
        encoding=new System.Text.UnicodeEncoding(); 
        break;    
    case EncodingType.UTF7: 
        encoding=new System.Text.UTF7Encoding(); 
        break;    
    case EncodingType.UTF8: 
        encoding=new System.Text.UTF8Encoding(); 
        break;    
    } 
    return encoding.GetString(bytes); 
}