4

我很难让一个小应用程序更快地工作。我不是开发人员,我花了一些时间才让它按原样工作。任何人都可以提供任何建议或替代代码来加快此过程,处理 10m 的输入文件大约需要 1 小时。

下面列出了代码,这里是输入文件的示例。

4401,imei:0000000000,2012-09-01 12:12:12.9999

using System;
using System.Globalization;
using System.IO;

class Sample 
{
    public static void Main(string[] args) 
    {
if (args.Length == 0)
                {
                    return;
                }


                using (FileStream stream = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {

                    using (StreamReader streamReader = new StreamReader(stream))
                    {
                        System.Text.StringBuilder builder = new System.Text.StringBuilder();
                        while (!streamReader.EndOfStream)
                        {
                            var line = streamReader.ReadLine();
                            var values = line.Split(',');
                            DateTime dt = new DateTime();
                            DateTime.TryParse(values[2], out dt);
                            values[2] = Convert.ToString(dt.Ticks);

                            string[] output = new string[values.Length];
                            bool firstColumn = true;
                            for (int index = 0; index < values.Length; index++)
                            {
                                if (!firstColumn)
                                    builder.Append(',');
                                builder.Append(values[index]);
                                firstColumn = false;

                            }
                            File.WriteAllText(args[1], builder.AppendLine().ToString());

                        }
                    }
                }
            }
}
4

2 回答 2

6

最大的性能损失是每次读取一行时,整个文件(到目前为止已处理)都会写回磁盘。为了快速获胜,请尝试将您的 StringBuilder 移出循环:

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            using (FileStream stream = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    while (!streamReader.EndOfStream)
                    {
                        var line = streamReader.ReadLine();
                        var values = line.Split(',');
                        DateTime dt = new DateTime();
                        DateTime.TryParse(values[2], out dt);
                        values[2] = Convert.ToString(dt.Ticks);

                        string[] output = new string[values.Length];
                        bool firstColumn = true;
                        for (int index = 0; index < values.Length; index++)
                        {
                            if (!firstColumn)
                                builder.Append(',');
                            builder.Append(values[index]);
                            firstColumn = false;
                        }
                        builder.AppendLine();
                    }
                }
            }

            File.WriteAllText(args[1], builder.ToString());

如果要进一步重构,请更改逗号分隔逻辑:

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            using (FileStream stream = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    while (!streamReader.EndOfStream)
                    {
                        var line = streamReader.ReadLine();
                        var values = line.Split(',');
                        DateTime dt = new DateTime();
                        DateTime.TryParse(values[2], out dt);
                        values[2] = Convert.ToString(dt.Ticks);

                        builder.AppendLine(string.Join(",", values));
                    }
                }
            }

            File.WriteAllText(args[1], builder.ToString());

编辑:为了避免内存使用,删除Stringbuilder并使用另一个FileStream写入磁盘。您提出的解决方案(使用 a List)仍将使用大量内存,并且可能会破坏较大的文件:

        using (FileStream input = File.Open(args[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (FileStream output = File.Create(args[1]))
        {
            using (StreamReader streamReader = new StreamReader(input))
            using (StreamWriter streamWriter = new StreamWriter(output))
            {
                while (!streamReader.EndOfStream)
                {
                    var line = streamReader.ReadLine();
                    var values = line.Split(',');
                    DateTime dt = new DateTime();
                    DateTime.TryParse(values[2], out dt);
                    values[2] = Convert.ToString(dt.Ticks);

                    streamWriter.WriteLine(string.Join(",", values));
                }
            }
        }
于 2012-10-11T01:33:36.260 回答
0

这是我发现可以解决此问题并处理大文件的方法。

感谢@Muzz 和@Vache 的帮助。

string line = ""; 
System.IO.StreamReader file = new System.IO.StreamReader("c:/test.txt"); 
List<string> convertedLines = new List<string>(); 
while ((line = file.ReadLine()) != null) 
{
    string[] lineSplit = line.Split(','); 
    DateTime dt = new DateTime(); 
    DateTime.TryParse(lineSplit[2], out dt); 
    lineSplit[2] = Convert.ToString(dt.Ticks); 
 
    string convertedline = lineSplit[0] + "," + lineSplit[1] + "," + lineSplit[2]; 
    convertedLines.Add(convertedline);
}
file.Close();
File.WriteAllLines("c:/newTest.txt", convertedLines);
于 2012-10-11T15:20:40.103 回答