BigMan
BigMan

Reputation: 83

Using a StreamWriter and StreamReader results in error "Stream not readable"

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

Answers (2)

user3285954
user3285954

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

thumbmunkeys
thumbmunkeys

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

Related Questions