Write to a File using CsvHelper in C# - c#

I tried to write to CSV file using CsvHelper in C#.
This is the link to the library http://joshclose.github.io/CsvHelper/
I used the code in web site.
Here is my code:
var csv = new CsvWriter(writer);
csv.Configuration.Encoding = Encoding.UTF8;
foreach (var value in valuess)
{
csv.WriteRecord(value);
}
It writes only a part of data to csv file.
Last rows were missing.
Could you please help with this.

You need to flush the stream. The Using statement will flush when out of scope.
using (TextWriter writer = new StreamWriter(#"C:\test.csv", false, System.Text.Encoding.UTF8))
{
var csv = new CsvWriter(writer);
csv.WriteRecords(values); // where values implements IEnumerable
}

when, I added this code after the loop code is working well
var csv = new CsvWriter(writer);
csv.Configuration.Encoding = Encoding.UTF8;
foreach (var value in valuess)
{
csv.WriteRecord(value);
}
writer.Close();
The problem occurred because I did not close the Connection

Assuming that writer is some kind of TextWriter, you should add a call to flush the contents before closing the writer:
writer.Flush()
If the last lines are missing, this is the most likely reason.

Adding to #greg's answer:
using (var sr = new StreamWriter(#"C:\out.csv", false, Encoding.UTF8)) {
using (var csv = new CsvWriter(sr)) {
csv.WriteRecords(values);
}
}

Related

C# How to delete certain rows from a CSV file and save it as a new CSV using CsvHelper?

I'm trying to delete certain rows from my CSV file but since I'm new to C# I can't figure out how to do it right.
I have this code that loads a CSV file and goes trough it.
using (var reader = new StreamReader(#"Data\myCSV.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Books>();
var books = records.ToImmutableArray();
for (int i = 0; i < books.Length; ++i)
{
if (books[i].title == "someTitle")
{
//Delete this row
}
}
//Overwrite old csv
}
But I cannot find the code that would delete the indicated row.
Any help is appreciated.
You could pull all off the records into memory and then write them back to the file.
List<Books> records;
using (var reader = new StreamReader(#"Data\myCSV.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
records = csv.GetRecords<Books>().ToList();
for (int i = 0; i < records.Count; ++i)
{
if (records[i].Title == "someTitle")
{
records.RemoveAt(i);
}
}
}
using (var writer = new StreamWriter(#"Data\myCSV.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.WriteRecords(records);
}
For a larger file you might want to read one record at a time to memory and write it immediately back to a temporary file. Then delete the original file and rename the temporary file.
using (var reader = new StreamReader(#"Data\myCSV.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
using (var writer = new StreamWriter(#"Data\myCSV_Temp.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
Books record;
csv.Read();
csv.ReadHeader();
csvWriter.WriteHeader(typeof(Books));
while (csv.Read())
{
record = csv.GetRecord<Books>();
if (record.Title != "someTitle")
{
csvWriter.NextRecord();
csvWriter.WriteRecord(record);
}
}
}
File.Delete(#"Data\myCSV.csv");
File.Move(#"Data\myCSV_Temp.csv", #"Data\myCSV.csv");
From https://github.com/JoshClose/CsvHelper/issues/1397:
CsvHelper is forward only, so you'll need to read through the existing file and write a new one.
There are too many ways of doing this not specifically using CsvHelper, hence i'm listing few suggestions you can try
Simplest solution without getting into details, if the file is small enough(in MBs), read all lines into a List or IEnumerable and then you can do any operation on that collection and write the collection back to the file.
if you are new to c# try out all basic file operations before working on the actual project . Follow a tutorial such as https://www.tutorialspoint.com/csharp/csharp_file_io.htm or videos on youtube
Text Files : https://www.youtube.com/watch?v=cST5TT3OFyg
File IO : https://www.youtube.com/watch?v=9mUuJIKq40M
Use free tools like LinqPad or dotnetfiddle to try small code snippets before writing a large program.
once you are comfortable working with files using .Net libraries, you can look at using libraries such as https://www.filehelpers.net/ which make it very easy to work with files with a lot of configurable options. They also have a lot of turials on their website to work with files.

How do I append CSV using CSV helper?

I went through documentation and I didn't see anything for it. I'm using the same exact write function from documentation but the problem is I also need to append. So far I've tried reading it than adding the CSV into a list than I write the list to CSV. Is there a better way I could append?
The exact write function I use with my own variables
var records = new List<Foo>
{
new Foo { Id = 1, Name = "one" },
};
using (var writer = new StreamWriter("path\\to\\file.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(records);
}
What I use to read but with my own variables:
using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Foo>();
}
Hopefully someone can help!
Use the StreamWriter(String, Boolean) constructor to specify you want to append to an existing file:
Initializes a new instance of the StreamWriter class for the specified file by using the default encoding and buffer size. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.
Parameters
path
String
The complete file path to write to.
append
Boolean
true to append data to the file; false to overwrite the file. If the specified file does not exist, this parameter has no effect, and the constructor creates a new file.
As for your CsvHelper CsvWriter, you need to configure it to omit the header depending on if you are appending or creating:
bool append = true;
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
config.HasHeaderRecord = !append;
using (var writer = new StreamWriter("path\\to\\file.csv", append))
{
using (var csv = new CsvWriter(writer, config))
{
csv.WriteRecords(records);
}
}

C# CSVWriter how to avoid getting empty line at the end of writing all lines to a file

I am using CSVWriter to write to csv by using the following link:
How to create csv with header and footer using LinqtoCsv or anything better in C#
But for some reason i am getting an empty line created at the end. Can anyone help me what am i doing wrong or how can i avoid getting an empty line?
Here is the code to create csv using csvwriter:
using (var writer = File.AppendText(outputCsv))
{
var csv = new CsvWriter(writer);
csv.Configuration.RegisterClassMap<CustomMap>();
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.QuoteNoFields = true;
csv.Configuration.Delimiter = "|";
csv.WriteRecords(asRunLogs.ToList());
csv.WriteRecord(new CSVFooterRecord()
{
FooterText =
$"TRAILER:{"qsaam_promos.csv"}|{DateTime.Now.ToString("ddMMyyHHmm")}|{asRunLogs.Count}"
});
}
When i open the file in Notepad++, i can see an empty line at the end.
Appreciate help with regard to this.
Thanks
You could do
writer.Write($"TRAILER:{"qsaam_promos.csv"}|{DateTime.Now.ToString("ddMMyyHHmm")}|{asRunLogs.Count}");
writer.Flush();
instead of
csv.WriteRecord(new CSVFooterRecord()
{
FooterText =
$"TRAILER:{"qsaam_promos.csv"}|{DateTime.Now.ToString("ddMMyyHHmm")}|{asRunLogs.Count}"
});

CsvHelper How can I save several classes in the same file

How can I save several classes in the same file with CsvHelper? For example, through the different sheets. I tried like this but unfortunately it does not work.
using (var writer = new CsvWriter(new StreamWriter(#"db.csv")))
{
writer.WriteRecords(this.Class1List);
writer.WriteRecords(this.Class2List);
}
try
using (var writer = new CsvWriter(new StreamWriter(#"db.csv", true)))
{
writer.WriteRecords(this.Class1List);
writer.WriteRecords(this.Class2List);
}

Overwriting Writer Issue

I'm writing a list to a file, the list gets data from the form app from text I type in. This works but it overwrites the file every time I start the form instead of saving it and adding new data. How Can I add "AppendAllLines" or "WriteAllLines" to this as a solution?
public List<String> listDeliveries()
{
List<String> listDeliveries = new List<string>();
using (StreamWriter writer = new StreamWriter("Database.txt"))
{
foreach (Delivery del in deliveries)
{
String delAsString = del.summary();
listDeliveries.Add(delAsString);
writer.WriteLine(delAsString);
}
}
return listDeliveries;
}
var listDeliveries = deliveries.Select(d=>d.summary()).ToList();
File.AppendAllLines("Database.txt", listDeliveries);
return listDeliveries;
You can use ToList to create your list and File.AppendAllLines to append the lines from the list:
List<string> listDeliveries = deliveries.Select(d => d.summary())
.ToList();
File.AppendAllLines("Database.txt", listDeliveries);
How Can I add "AppendAllLines" or "WriteAllLines" to this as a solution?
Well it looks like you just want:
List<String> listDeliveries = deliveries.Select(x => x.summary()).ToList();
File.AppendAllLines("Database.txt", listDeliveries);
return listDeliveries;
(Yes, you can create the StreamWriter with true as the second argument, but AppendAllLines is simpler...)
You can use
using (StreamWriter writer = new StreamWriter("Database.txt", true))
To append rather than overwrite
Use overloaded constructor that allows you to specify whether to append or not. The default is false
StreamWriter writer = new StreamWriter("Database.txt", true)
When you create the StreamWriter, pass in a boolean that will tell it to append data to the file instead of overwrite.
using (StreamWriter writer = new StreamWriter("Database.txt", true))

Categories