LINQ to Text Files

这篇文章,我们将开发一个操作文本文件的示例程序,示例程序演示了从 CSV 文件中获取信息的方法。

CSV 的含义是逗号分割的值(comma-separated values),也就是说在 CSV 文件中,各个不同值之间是通过逗号分割的。

下面给出了我们将操作的 CSV 文件:

#Books (format: ISBN, Title, Authors, Publisher, Date, Price)
0735621632,CLR via C#,Jeffrey Richter,Microsoft Press,02-22-2006,59.99
0321127420,Patterns Of Enterprise Application Architecture,Martin Fowler,Addison-Wesley, 11-05-2002,54.99
0321200683,Enterprise Integration Patterns,Gregor Hohpe,Addison-Wesley,10-10-2003,54.99
0321125215,Domain-Driven Design,Eric Evans,Addison-Wesley Professional,08-22-2003,54.99
1932394613,Ajax In Action,Dave Crane;Eric Pascarello;Darren James,Manning Publications,10-01-2005,44.95

或者从这里下载 CSV 格式文件:https://cdn.vinanysoft.com/blog/02/16/books.csv

该 CSV 文件包含了一些有关图书的信息。为了能够读取到 CSV 中的数据,第一步就是打开该文件并取得其中的每一行。得到文件内容之后,接下来就是过滤掉其中的注释。

下面就是实现这部分功能的代码:

1
2
3
var books = from line in File.ReadAllLines("books.csv")
            where !line.StartsWith("#")
            select line;

下一步要做的是,将每一行分割成小的部分。这个操作可以使用 string 类型的 Split 方法来实现。在接下来的查询中肯定要用到分割出来的每个部分,不过考虑到性能,我们最好只调用一次 Split。这时正是 let 子句大显身手的时候。let 子句能够求出某个表达式的值,并用一个新的标识表示该值。这里我们就用 let 子句来保存由一行文本分割出的每个部分。随后即可使用 select 子句将其封装到一个匿名类型中。

下面的代码给出了完整的查询语句:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var books = from line in File.ReadAllLines("books.csv")
            where !line.StartsWith("#")
            let parts = line.Split(',')
            select new
            {
                Isbn = parts[0],
                Title = parts[1],
                Publisher = parts[3]
            };

foreach (var book in books)
{
    Console.WriteLine($"Isbn={book.Isbn,-15} Title={book.Title,-50} Publisher={book.Publisher}");
}

输出:

Isbn=0735621632      Title=CLR via C#                                         Publisher=Microsoft Press
Isbn=0321127420      Title=Patterns Of Enterprise Application Architecture    Publisher=Addison-Wesley
Isbn=0321200683      Title=Enterprise Integration Patterns                    Publisher=Addison-Wesley
Isbn=0321125215      Title=Domain-Driven Design                               Publisher=Addison-Wesley Professional
Isbn=1932394613      Title=Ajax In Action                                     Publisher=Manning Publications

这就是从简单 CSV 中读取数据所需要做的全部工作。这个示例程序只能够处理最简单的 CSV 文件。对于转义逗号或其他高级 CSV 功能则无能为力。若想在真实的示例程序中使用,你还需要对上述代码进行完善,或是使用其他方法。

此外,该代码的执行效率也较为低下。在后面的文章中(链接:https://www.vinanysoft.com/c-sharp/linq-performance-analysis/),我们将会对其进行改进。

参考:

Fabrice Marguerie,Steve Eichert,Jim Wooley.LINQ in Action.Manning Publications,2008-2-14. http://linqinaction.net/