Reputation: 1456
I am working with some files and converting from one format to another. My function is a step in a logic app and the output of my function results in a file being created, using the pre-defined step "Create file (FTP)" where the file content is the body of my function.
I am trying to change the way my function works at the moment to have a memory friendly version. I was trying to achieve some form of 'streaming' so that I essentially only have one object in memory at a given time when deserializing.
I have tried something along the lines of the below and while it doesn't throw any errors I am not getting the expected output.
[FunctionName("Transform")]
public static async Task<HttpResponseMessage> Import([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
var doc = XDocument.Load(await req.Content.ReadAsStreamAsync());
var memoryStream = new MemoryStream();
if (doc.Root != null)
{
var ns = doc.Root.GetDefaultNamespace();
var query = from c in doc.Descendants(ns + "person")
select c;
var serializer = new XmlSerializer(typeof(Person));
var persons = new List<Person>();
foreach (var Person in query)
{
var personRecord = (Person)serializer.Deserialize(person.CreateReader());
persons.Add(personRecord);
}
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(persons);
streamWriter.Flush();
memoryStream.Flush();
}
}
return new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StreamContent(memoryStream)
};
}
When I debug my function locally and make a request to it via Postman I simply get a "could not load response". I was, if all worked well, expecting something like a csv output e.g.
John, Doe, 123
Mary, Jane, 456
I am wondering if the idea is good at all? At least that's what I am thinking at the moment, I just can't figure out how to do it.
Cheers
Upvotes: 2
Views: 5251
Reputation: 33379
The way you're using StreamWriter
is causing the MemoryStream
to be disposed of. By default the StreamWriter
assumes ownership of the Stream
it is handed and will dispose of it when it is disposed (or GC'd).
You'll need to use the constructor overload that takes (Stream, Encoding, int, bool)
where the bool
is named leaveOpen
and you need to set that to true
. I had to double check, but there is no simpler overload of just (Stream, bool)
. You'd probably want to do something like:
new StreamWriter(memoryStream, Encoding.UTF8Encoding, bufferSize:8192, leaveOpen:true)
However you should really decide what encoding works best for you and what bufferSize
might make the most sense for your workload.
Upvotes: 2