Stream was not readable error - c#

I am getting the message "Stream was not readable" on the statement:
using (StreamReader sr = new StreamReader(ms))
I have tried the tips posted here without success. Thanks for the help.
This is my code:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Conflict));
//Serialize Conflicts array to memorystream as XML
using (MemoryStream ms = new MemoryStream())
{
using (StreamWriter sw = new StreamWriter(ms))
{
foreach (Conflict ct in Conflicts)
xmlSerializer.Serialize(sw, ct);
sw.Flush(); //Site tip
ms.Position = 0; //Site tip
}
//Retrieve memory stream to string
using (StreamReader sr = new StreamReader(ms))
{
string conflictXml = String.Format(CultureInfo.InvariantCulture, "{0}</NewDataSet>",

When this block of code completes, it will also dispose the attached MemoryStream
using (StreamWriter sw = new StreamWriter(ms))
{
foreach (Conflict ct in Conflicts)
xmlSerializer.Serialize(sw, ct);
sw.Flush(); //Site tip
ms.Position = 0; //Site tip
}
Remove the using statement, and dispose the stream manually after you are done with it
StreamWriter sw = new StreamWriter(ms);
foreach (Conflict ct in Conflicts)
xmlSerializer.Serialize(sw, ct);
sw.Flush(); //Site tip
ms.Position = 0; //Site tip
// other code that uses MemoryStream here...
sw.Dispose();

Try this instead (assuming Conflicts is of type List<Conflict>):
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Conflict>));
StringWriter sw = new StringWriter();
xmlSerializer.Serialize(sw, Conflicts);
string conflictXml = sw.GetStringBuilder().ToString();

Related

Download byte array from stream writer

Hi I am trying to make working this piece of code, after the copy of the word file template into a memory stream, read it and replace some text, I would convert the stream writer to byte array which will be used to download the result. Thanks in advance
public byte[] GetWordFile()
{
try
{
string sourceFile = Path.Combine("C:/[...]/somefile.docx");
using (MemoryStream inStream = new MemoryStream())
{
using (Stream fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read))
{
fs.CopyTo(inStream);
}
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(inStream, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
docText = docText.Replace("numpol", "HAHAHHAHA");
using (MemoryStream outStream = new MemoryStream())
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
sw.Flush();
sw.BaseStream.CopyTo(outStream);
outStream.Position = 0;
return outStream.ToArray();
}
}
}
}
catch (Exception ex)
{
///...
}
}

asp.net Web API csv helper writing to the stream doesn't work

My initial requirement is to let the user download a file from object list for that I found this solution https://stackoverflow.com/a/49207997/11178128,
But the problem is when it comes to this line
bin = stream.ToArray();
there are no streams written to it. So the bin comes as an empty array.
What could be the problem?
Also, I'm making my web API available through a windows service. And for some reason System.Web.HttpContext.Current.Response gives me null. any idea why it can be?
Thanks in advance.
This is the code i have so far
List<Device> devices;
using (StreamReader r = new StreamReader(String.Format(#"{0}\deviceList.json", savefilePath)))
{
string json = r.ReadToEnd();
devices = JsonConvert.DeserializeObject<List<Device>>(json);
}
byte[] bin;
//String.Format(#"{0}\devices.csv", savefilePath)
using (MemoryStream stream = new MemoryStream())
using (TextWriter textWriter = new StreamWriter(stream))
using (CsvWriter csv = new CsvWriter(textWriter))
{
csv.Configuration.ShouldQuote = (field, context) => false;
csv.WriteRecords(devices);
bin = stream.ToArray();
}
This is related to another question, CsvHelper not writing anything to memory stream.
You just need to change your using statements so that the StreamWriter gets flushed before calling stream.ToArray();
List<Device> devices;
using (StreamReader r = new StreamReader(String.Format(#"{0}\deviceList.json", savefilePath)))
{
string json = r.ReadToEnd();
devices = JsonConvert.DeserializeObject<List<Device>>(json);
}
byte[] bin;
//String.Format(#"{0}\devices.csv", savefilePath)
using (MemoryStream stream = new MemoryStream())
{
using (TextWriter textWriter = new StreamWriter(stream))
using (CsvWriter csv = new CsvWriter(textWriter))
{
csv.Configuration.ShouldQuote = (field, context) => false;
csv.WriteRecords(devices);
}
bin = stream.ToArray();
}
Actually, after a bit of struggling, Found that i was missing this line.
textWriter.Flush();
As mentioned in the below reply I had to flush the textWriter object in order to write to the file. Here is the working code.
byte[] data;
using (MemoryStream stream = new MemoryStream())
using (TextWriter textWriter = new StreamWriter(stream))
using (CsvWriter csv = new CsvWriter(textWriter))
{
csv.Configuration.RegisterClassMap<DeviceMap>();
csv.Configuration.ShouldQuote = (field, context) => false;
csv.WriteRecords(values);
textWriter.Flush();
data = stream.ToArray();
}
return data;
using (var ms = new MemoryStream())
{
using (var writer = new StreamWriter(ms))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords(dbresponse);
} // the closing tag here is important!!It flush the streamwriter
ms.ToArray(); // or ms.GetBuffer()
}
Now the ms.ToArray() will contain the data from csvHelper
For a field variant - for example a list, which won't work using the writerecords method - you will need to use writefield. I am just submitting this here as this trifling issue caused me none too little pain.
Here is an async example:
var result = await GetListOfString();
using (var ms = new MemoryStream())
{
using (var writer = new StreamWriter(ms))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
foreach (var value in result)
{
csv.WriteField(value);
await csv.NextRecordAsync();
}
await writer.FlushAsync();
return ms.ToArray();
}
}

Exception in saving word document

When I execute the below code to save the word file following exception occurs.please help me to correct the issue.thanks.
Cannot get stream with FileMode.Create, FileMode.CreateNew, FileMode.Truncate, FileMode.Append when access is FileAccess.Read.
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(path, false))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
//Regex regexText = new Regex("<var_Date>");
docText = docText.Replace("<var_Date>", DateTime.Now.ToString("MMM dd,yyyy"));
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
sw.Write(docText);
}
Right here:
WordprocessingDocument.Open(path, false))
The second argument is isEditable, you passed false. So you've opened it as read-only.
Ref: https://msdn.microsoft.com/en-us/library/cc562234.aspx

MemoryStream - Cannot access a closed Stream

Hi why using (var sw = new StreamWriter(ms)) returns Cannot access a closed Stream exception. Memory Stream is on top of this code.
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms))
{
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
} //error here
}
What the best way to fix it ?
Thanks
This is because the StreamReader closes the underlying stream automatically when being disposed of. The using statement does this automatically.
However, the StreamWriter you're using is still trying to work on the stream (also, the using statement for the writer is now trying to dispose of the StreamWriter, which is then trying to close the stream).
The best way to fix this is: don't use using and don't dispose of the StreamReader and StreamWriter. See this question.
using (var ms = new MemoryStream())
{
var sw = new StreamWriter(ms);
var sr = new StreamReader(ms);
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
Console.WriteLine(sr.ReadToEnd());
}
If you feel bad about sw and sr being garbage-collected without being disposed of in your code (as recommended), you could do something like that:
StreamWriter sw = null;
StreamReader sr = null;
try
{
using (var ms = new MemoryStream())
{
sw = new StreamWriter(ms);
sr = new StreamReader(ms);
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
Console.WriteLine(sr.ReadToEnd());
}
}
finally
{
if (sw != null) sw.Dispose();
if (sr != null) sr.Dispose();
}
Since .net45 you can use the LeaveOpen constructor argument of StreamWriter and still use the using statement. Example:
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms, leaveOpen:true))
{
sw.WriteLine("data");
sw.WriteLine("data 2");
}
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
}
When the using() for your StreamReader is ending, it's disposing the object and closing the stream, which your StreamWriter is still trying to use.
The problem is this block:
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
When the StreamReader is closed (after leaving the using), it closes it's underlying stream as well, so now the MemoryStream is closed. When the StreamWriter gets closed, it tries to flush everything to the MemoryStream, but it is closed.
You should consider not putting the StreamReader in a using block.
when it gets out from the using statement the Dispose method will be called automatically closing the stream
try the below:
using (var ms = new MemoryStream())
{
var sw = new StreamWriter(ms);
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
}
You have to leave the stream open to be able to read it.
the "StreamWriter" closes it after it is done writing
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms, leaveOpen: true)))
{
sw.WriteLine("data");
sw.WriteLine("data 2");
ms.Position = 0;
using (var sr = new StreamReader(ms))
{
Console.WriteLine(sr.ReadToEnd());
}
} //error here
}
In my case (admittedly very arcane and not likely to be reproduced often), this was causing the problem (this code is related to PDF generation using iTextSharp):
PdfPTable tblDuckbilledPlatypi = new PdfPTable(3);
float[] DuckbilledPlatypiRowWidths = new float[] { 42f, 76f };
tblDuckbilledPlatypi.SetWidths(DuckbilledPlatypiRowWidths);
The declaration of a 3-celled/columned table, and then setting only two vals for the width was what caused the problem, apparently. Once I changed "PdfPTable(3)" to "PdfPTable(2)" the problem went the way of the convection oven.

How to find out whether a memory stream is filled properly

The code below tries to fill the message byte array with some simple text until the buffer is filled.
byte[] message = new byte[1024];
using (MemoryStream memoryStream = new MemoryStream(message, true))
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream, Encoding.ASCII))
{
while (???)
streamWriter.WriteLine("Hello World!");
}
}
What should be in the while(???) statement?
byte[] message = new byte[1024];
using (MemoryStream memoryStream = new MemoryStream(message, true))
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream, Encoding.ASCII))
{
var lineToAdd = "Hello World!";
while (memoryStream.Length - memoryStream.Position > lineToAdd.Length)
{
streamWriter.WriteLine(lineToAdd);
streamWriter.Flush();
}
}
}
OR
using (MemoryStream memoryStream = new MemoryStream(message, true))
using (StreamWriter streamWriter = new StreamWriter(memoryStream, Encoding.ASCII))
{
streamWriter.AutoFlush = true;
var lineToAdd = "Hello World!";
while (memoryStream.Length - memoryStream.Position > lineToAdd.Length)
streamWriter.WriteLine(lineToAdd);
}

Categories

Resources