Reputation: 83
I am trying to save data to a csv file but want to ensure that the data that I am about to save isn't already pressent in the csv file. Because of this I want to read the file first and then save the data.
FileStream writer = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
FileStream reader = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (StreamWriter sw = new StreamWriter(writer))
{
if (response.Datapoints.Count != 0)
{
foreach (var datapoint in response.Datapoints)
{
sb = new StringBuilder();
toBeSaved = new string[] { nameSpace, metric, instanceId, datapoint.Timestamp.ToString()};
foreach (string str in toBeSaved)
{
if (str == toBeSaved.Last())
{
sb.Append(str);
}
else
{
sb.Append(str);
sb.Append(",");
}
}
// here I get the error that the "Stream is not Readable"
using (StreamReader sr = new StreamReader(reader))
{
if (sr.ReadLine() != sb.ToString())
{ // only write the data if it is not already there in the file
sw.WriteLine(sb.ToString());
}
}
}
Upvotes: 0
Views: 8138
Reputation: 4749
Assuming you are using .Net 4.5 or later it can be set in StreamReader constructor to leave the stream open:
http://msdn.microsoft.com/en-us/library/gg712952(v=vs.110).aspx
public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
Upvotes: 1
Reputation: 20764
This using statement will dispose the reader
:
using (StreamReader sr = new StreamReader(reader))
The disposing of the StreamReader
will also dispose reader
.
When you access it the next loop iteration it is disposed, hence the error message.
You can circumvent this by creating a new FileStream
reader every loop iteration, or by reusing the StreamReader
and disposing it after the loop.
I would use a different approach, that is likely more performant.
Unless your input file is really big, read it completely into memory at the beginning:
var lines = File.ReadLines();
then before you write to the csv file:
if(!lines.Contains(sb.ToString())
sw.WriteLine(sb.ToString());
Upvotes: 2