Skip to content

Instantly share code, notes, and snippets.

@HeshamMeneisi
Last active June 2, 2018 22:09
Show Gist options
  • Save HeshamMeneisi/b6da340b4dfb9e28212e9d1f7ab45ae5 to your computer and use it in GitHub Desktop.
Save HeshamMeneisi/b6da340b4dfb9e28212e9d1f7ab45ae5 to your computer and use it in GitHub Desktop.
CSV Encoding/Decoding from/to C# IEnumerable
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace CSV
{
class CSVDecoder
{
/// <summary>
/// Decodes single-line CSV line by line on-demand
/// </summary>
/// <typeparam name="T">Type with a T(Dictionary) constructor</typeparam>
/// <param name="path">CSV file path</param>
/// <param name="commentStart">A comment start string for ignored column(s)</param>
/// <returns></returns>
public static IEnumerable<T> DecodeSLConst<T>(string path, string commentStart = null)
{
string line;
Dictionary<string, string> dict = new Dictionary<string, string>();
using (var sr = new StreamReader(File.OpenRead(path)))
{
line = sr.ReadLine();
string[] columns = line.Split(',').ToArray();
while (!sr.EndOfStream)
{
try
{
line = sr.ReadLine();
string[] values = line.Split(',');
if (values.Length == 0)
continue;
dict = new Dictionary<string, string>();
for (int i = 0; i < columns.Length; i++)
if (commentStart == null || dict[columns[i]].StartsWith(commentStart))
dict[columns[i]] = values[i];
}
catch (Exception ex)
{
throw new Exception("Invalid CSV file. " + ex.Message);
}
yield return (T)Activator.CreateInstance(typeof(T), dict);
}
}
}
}
class CSVEncoder
{
/// <summary>
/// Encodes the public properties of the given objects to a CSV file asynchornously
/// </summary>
/// <typeparam name="T">Object Type</typeparam>
/// <param name="data">The IEnumerable data</param>
/// <param name="path">CSV file path</param>
public static async Task EncodeToFileAsync<T>(IEnumerable<T> data, string path)
{
Type type = typeof(T);
PropertyInfo[] properties = type.GetProperties();
using (var f = File.Create(path))
using (var sw = new StreamWriter(f))
{
StringBuilder sb = new StringBuilder();
foreach (PropertyInfo property in properties)
{
sb.Append(property.Name);
sb.Append(',');
}
await sw.WriteLineAsync(sb.ToString().TrimEnd(','));
float i = 0;
foreach (var obj in data)
{
sb = new StringBuilder();
foreach (PropertyInfo property in properties)
{
sb.Append("\"");
sb.Append(property.GetValue(obj, null).ToString().Replace("\"", "\"\""));
sb.Append("\",");
}
await sw.WriteLineAsync(sb.ToString().TrimEnd(','));
i++;
if (i % 100 == 0)
Debug.WriteLine(i / data.Count());
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment