在c#中操作文本文件
本文关键字:作文本 文件 操作 | 更新日期: 2023-09-27 18:13:43
我被分配了一个项目,该项目需要一个c#控制台应用程序来操作文本文件。文本文件是一个bcp表转储文件。程序应该能够:
- 根据用户 给出的列将文件拆分为多个文件
- 从输出中包含或排除分割列
目前,我正在读取文件如下:
var groupQuery = from name in File.ReadAllLines(fileName)
.Skip(skipHeaderRow)
let n = name.Split(delimiterChars)
group name by n[index] into g
// orderby g.Key
select g;
我担心我可能会遇到内存问题,因为一些文件可以有超过200万条记录,每行约2617字节
如果您确信您的程序只需要顺序访问… bcp转储文件,使用StreamReader类读取该文件。这个类针对顺序访问进行了优化,它将文件作为流打开,因此内存问题不应该困扰您。此外,您可以通过从该类的不同构造函数初始化来增加流的缓冲区大小,以便有更大的内存块可供处理。
如果你想随机访问你的文件碎片… go为内存映射文件。确保在文件的有限部分上创建视图访问器。在mmf链接中给出的示例代码解释了如何在大文件上创建小视图。
编辑:我有在我的答案中使用mmf的代码,但我现在已经删除了它,因为我意识到…尽管实际上group by是惰性的,但它也是一个非流 LINQ操作符。因此,它必须读取您的整个bcp转储,才能最终给出结果。这意味着:
- StreamReader显然是一个更好的方法为您 。确保您将缓冲区增加到最大可能;
- 你的LINQ将需要一些时间,当它被操作员击中组,只有在整个文件读取完成后才会恢复生命。
尝试使用Buffered Streams来读写文件,而不将它们完全加载到内存中。
using (FileStream fs = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
using (StreamReader sr = new StreamReader(fs)) {
string line = sr.ReadLine();
string lineA = null;
string lineB = null;
while ((line != null)) {
// Split your line here into lineA and lineB
// and write using buffered writer.
line = sr.ReadLine();
}
}
}
(离这里)
这个想法是一行一行地读取文件,而不是将整个东西加载到内存中,按照你想要的方式拆分它,然后将拆分的行逐行写入输出文件。
别白费力气了。考虑使用FileHelpers之类的库。
http://www.filehelpers.net/example/QuickStart/ReadWriteRecordByRecord/var engine = new FileHelperAsyncEngine<Customer>();
using(engine.BeginReadFile(fileName))
{
var groupQuery =
from o in engine
group name by o.CustomerId into g
// orderby g.Key
select g;
foreach(Customer cust in engine)
{
Console.WriteLine(cust.Name);
}
}
你仍然会遇到组和排序函数的内存问题,因为所有的记录都需要在内存中进行分组和排序。