I wrote the following (static) class to read files easily in C#. However, it is a static class, so I wonder if there would be a gain to make it a non static method (and therefore, passing arguments as the separator and the path as attributes of the class).
Besides, the OrderedDictionary class may not be a good choice (it is not generic but it preserves the order of the columns), and I don't know if there is a nice workaround for this.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
namespace MySolution.FileUtils
{
/// <summary>
/// Various helpers to read through the lines of a file.
/// </summary>
public static class LinesEnumerator
{
public static string ReadFirstLine(string path)
{
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sr = new StreamReader(fs))
{
return sr.ReadLine();
}
}
/// <summary>
/// Enumerates the lines of a file.
/// </summary>
/// <param name="path">The path of the file.</param>
/// <param name="maxLines">The maximum number of lines to read.</param>
/// <returns>The lines of a file, as a IEnumerable</returns>
public static IEnumerable<string> LinesReader(string path, int maxLines = Int32.MaxValue)
{
string line;
int lineNumber = 0;
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sr = new StreamReader(fs))
{
while ((line = sr.ReadLine()) != null && lineNumber < maxLines)
{
lineNumber++;
yield return line;
}
}
}
/// <summary>
/// Reads the lines of a CSV file and enumerates them through a csv file
/// </summary>
/// <param name="path">Path to the CSV file</param>
/// <param name="separator">Separator used by the CSV file</param>
/// <returns>A collection of ordered dictionaries, corresponding to the lines of the file</returns>
public static IEnumerable<OrderedDictionary> DictReaderCSV(string path, char separator)
{
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (StreamReader sr = new StreamReader(fs))
{
string[] header = sr.ReadLine().Split(separator);
string line = "";
while ((line = sr.ReadLine()) != null)
{
string[] splittedLine = line.Split(separator);
OrderedDictionary od = new OrderedDictionary();
for (int i = 0; i < header.Length; i++)
od.Add(header[i], splittedLine[i]);
yield return od;
}
}
}
}
}