C# 逐行读取文件的最快方法?

C# 逐行读取文件的最快方法?,c#,arrays,C#,Arrays,我目前有一个.TXT文件,我正在尝试读取所有行,并对它们进行排序,然后按顺序显示它们 这是我的 string inFile = "Z:/Daniel/Accounts.txt"; string outFile = "Z:/Daniel/SortedAccounts.txt"; var contents = File.ReadAllLines(inFile); Array

我目前有一个.TXT文件,我正在尝试读取所有行,并对它们进行排序,然后按顺序显示它们

这是我的

                string inFile = "Z:/Daniel/Accounts.txt";
                string outFile = "Z:/Daniel/SortedAccounts.txt";
                var contents = File.ReadAllLines(inFile);
                Array.Sort(contents);
                File.WriteAllLines(outFile, contents);

                int i = 0;
                int lineCount = File.ReadLines("Z:/Daniel/SortedAccounts.txt").Count();
                do
                {
                    string accounts = File.ReadLines("Z:/Daniel/SortedAccounts.txt").Skip(i).Take(1).First();
                    //First Name
                    int pFrom1 = accounts.IndexOf("#1#") + "#1#".Length;
                    int pTo1 = accounts.LastIndexOf("#2#");
                    String accountFirstName = accounts.Substring(pFrom1, pTo1 - pFrom1);
                    //Last Name
                    int pFrom2 = accounts.IndexOf("#2#") + "#2#".Length;
                    int pTo2 = accounts.LastIndexOf("#3#");
                    String accountLastName = accounts.Substring(pFrom2, pTo2 - pFrom2);
                    //Email
                    int pFrom3 = accounts.IndexOf("#3#") + "#3#".Length;
                    int pTo3 = accounts.LastIndexOf("#4#");
                    String accountEmail = accounts.Substring(pFrom3, pTo3 - pFrom3);
                    //Phone Number
                    int pFrom4 = accounts.IndexOf("#4#") + "#4#".Length;
                    int pTo4 = accounts.LastIndexOf("#5#");
                    String accountNumber = accounts.Substring(pFrom4, pTo4 - pFrom4);
                    //Preferred Contact
                    int pFrom5 = accounts.IndexOf("#5#") + "#5#".Length;
                    int pTo5 = accounts.LastIndexOf("#6#");
                    String accountPreferredContact = accounts.Substring(pFrom5, pTo5 - pFrom5);
                    //Populate Combobox
                    accountComboBox.Items.Add(accountLastName + "," + accountFirstName);
                    i = i + 1;
                } while (i < lineCount);
string infle=“Z:/Daniel/Accounts.txt”;
string outFile=“Z:/Daniel/SortedAccounts.txt”;
var contents=File.ReadAllLines(infle);
数组。排序(内容);
File.writeAllines(输出文件,内容);
int i=0;
int lineCount=File.ReadLines(“Z:/Daniel/SortedAccounts.txt”).Count();
做
{
string accounts=File.ReadLines(“Z:/Daniel/SortedAccounts.txt”).Skip(i).Take(1.First();
//名字
int pFrom1=accounts.IndexOf(“#1#”)+“#1#”;
int pTo1=accounts.LastIndexOf(“#2#”);
字符串accountFirstName=accounts.Substring(pFrom1,pTo1-pFrom1);
//姓
int pFrom2=accounts.IndexOf(“#2#”)+“#2#”;
int pTo2=accounts.LastIndexOf(“#3#”);
字符串accountLastName=accounts.Substring(pFrom2,pTo2-pFrom2);
//电子邮件
int pFrom3=accounts.IndexOf(“#3#”)+“#3#”;
int pTo3=accounts.LastIndexOf(“#4#”);
字符串accountEmail=accounts.Substring(pFrom3,pTo3-pFrom3);
//电话号码
int pFrom4=accounts.IndexOf(“#4#”)+“#4#”;
int pTo4=accounts.LastIndexOf(“#5#”);
字符串accountNumber=accounts.Substring(pFrom4,pTo4-pFrom4);
//首选联系人
int pFrom5=accounts.IndexOf(“#5#”)+“#5#”;
int pTo5=accounts.LastIndexOf(“#6#”);
字符串accountPreferredContact=accounts.Substring(pFrom5,pTo5-pFrom5);
//填充组合框
accountComboBox.Items.Add(accountLastName+,“+accountFirstName);
i=i+1;
}而(i
下面是
Accounts.txt
中的一个示例

#1#丹尼尔#2#莫斯#3#dasdnmasdda@gmail.com#4#31012304#5#电子邮件#6# #1#丹尼尔#2#摩萨#3#dddasdsa@gmail.com#4#310512304#5#电子邮件#6# #1#丹斯代尔#2#莫斯达#3#dasdsdssa@gmail.com#4#31121234#5#文本#6# #1#Danasdl#2#Mosasaa#3#daasda@gmail.com#4#310123304#5#电子邮件#6# #1#丹达塞尔#2#穆阿萨德#3#daasdsda@gmail.com#4#3123551234#5#文本#6# #1#Danasdl#2#Mossdsadd#3#daasddsa@gmail.com#4#310213304#5#文本#6#

问题是,有时,
Accounts.txt
将有超过10000行,然后需要一段时间才能加载程序

我写的代码有没有更快的实现?

我的建议:

  • 逐行读取文件,如
    file.readlines
    ,边读边流,而不是读取整个文件(尤其是不要像现在这样读取两次文件!)
  • 对于每一行,应用一个已编译的正则表达式,从该字符串中获取所需的值
  • 创建一个account类(或者我猜只是一个字符串值),根据需要保存2中的所有值。看起来您的循环只关心其中两个字符串(
    accountLastName
    accountFirstName
  • 将这些添加到不是组合框项目的列表中
  • 如果需要排序,请使用linq/sort对它们进行排序(尽可能少地进行排序,尽可能晚地进行排序),例如
    items.OrderBy(x=>x.LastName)。然后按(y=>y.FirstName)
    或其他任何方式进行排序
  • 将整个项目块添加到组合框的最末端,而不是一次添加一个。理想情况下,类似于
    combobox.Items.AddRange(Items)
    (每次添加一个项目时,许多combobox/etc集合可能会触发一个集合更改事件,如果添加1000个项目,这可能会造成大量开销)

  • 所有代码都应该按照下面的方式进行重构。您需要衡量这两种方法的性能

    const string inFile = "Z:/Daniel/Accounts.txt";
                    const string outFile = "Z:/Daniel/SortedAccounts.txt";
                    string[] contents = File.ReadAllLines(inFile);
                    Array.Sort(contents);
                    File.WriteAllLines(outFile, contents);
    
                    IEnumerable<string> lines = File.ReadLines("Z:/Daniel/SortedAccounts.txt");
                    foreach (string line in lines)
                    {
    
                        //First Name
                        string[] data = Regex.Split(line, "[#\\d#]");
                        string accountFirstName = data[0];
    
                        string accountLastName = data[1];
    
                        string accountEmail = data[2];
    
                        //Phone Number
                        string accountNumber = data[3];
    
                        //Preferred Contact
                        string accountPreferredContact = data[4];
    
                        //Populate Combobox
                        //accountComboBox.Items.Add(accountLastName + "," + accountFirstName);
                    }
    

    一般来说,读取每一行并对其进行处理可能比将整个文件读入内存中的一个巨大字符串并对其进行解析更快。不过,还有很多类似的问题。您好,您已经加载了字符串[]内容中的所有文本,为什么只使用它来循环所有内容,而不是从输出文件中再次读取?@johngarder,在我看来,该线程似乎在说我正在做的已经是最快的方法。这是不幸的,而不是所有的string.indexof/lastindexof,对于一个在一次传递中获得所有值的已编译正则表达式来说,这看起来是一个非常好的例子。您需要:读取文件、对其进行排序、将其写回、再次读取、应用大量字符串操作,然后将项目添加到组合框中。最后一步可能是这一切中最糟糕的部分,这取决于这是什么ui技术。其他一切对我来说都很有意义,但我已经被卡住了,哈哈。我不能让正则表达式工作吗?如何将其添加到组合框中?同样,取消注释行John Gardner说“将整个项目块添加到组合框的最末端,而不是一次添加一个。理想情况下类似于combobox.items.AddRange(项目)”。我该怎么做呢?代码修改了,但您需要衡量性能
    class Account
        {
            public string FirstName { get; set; }
    
            public string LastName { get; set; }
    
            public string Email { get; set; }
    
            public string Number { get; set; }
    
            public string PreferredContact { get; set; }
    
        }
                accountComboBox.Items.AddRange(
                    lines.Select(line => Regex.Split(line, "[#\\d#]")).Select(data => new Account
                    {
                        FirstName = data[0],
                        LastName = data[1],
                        Email = data[2],
                        Number = data[3],
                        PreferredContact = data[4]
                    }).Select(item => string.Format("{0},{1}", item.LastName, item.FirstName)).ToArray()
                    );