逐行读取文件的最快方法
本文关键字:方法 读取 文件 逐行 | 更新日期: 2023-09-27 18:32:16
我目前有一个.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);
Accounts.txt
里面的一个例子是
#1#丹尼尔#2#Mos#3#dasdnmasdda@gmail.com#4#31012304#5#电子邮件#6# #1#丹尼尔#2#莫萨#3#dddasdsa@gmail.com#4#310512304#5#电子邮件#6# #1#Dansdael#2#Mossdsa#3#dasdsdssa@gmail.com#4#31121234#5#TEXT#6# #1#Danasdl#2#Mosasaa#3#daasda@gmail.com#4#310123304#5#EMAIL#6# #1#丹达塞尔#2#Moasddand#3#daasdsda@gmail.com#4#3123551234#5#文本#6# #1#Danasdl#2#Mossdsadd#3#daasddsa@gmail.com#4#310213304#5#TEXT#6#
问题是,有时Accounts.txt
将有超过 10,000 行,然后程序加载需要一段时间。
我编写的代码是否有更快的实现?
我的建议:
- 逐行读取文件,例如
file.readlines
,随心所欲地流式传输而不是读取整个文件(尤其是不要以两次方式读取文件! - 对于每一行,应用一个已编译的正则表达式,该正则表达式从该字符串中获取所需的值
- 创建一个帐户类(或者我猜只是一个字符串值),根据需要保存 2 中的所有值。 看起来你的循环只关心其中的 2 个字符串(
accountLastName
和accountFirstName
) - 将它们添加到不是组合框项目的列表中。
- 如果需要排序,请使用 linq/sort 对它们进行排序(尽可能少地排序,尽可能晚地排序),比如
items.OrderBy( x => x.LastName ).ThenBy( 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);
}
编辑"使用添加范围"
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()
);