question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Large stream writing. Try use StreamWriter

See original GitHub issue

I read some sample code:

IWorkbook workbook = new XSSFWorkbook();
using (FileStream stream = new FileStream("outfile.xlsx", FileMode.Create, FileAccess.Write))
{
  workbook.Write(stream);
}  

There is only a Write method to usage. In this case, we need write bytes to file. that would consume disk I/O. Think about scenario when user generate excel data and return excel file. The normal way to achieve that is like below:

var stream = new MemoryStream();
workbook.Write(stream);
return File(stream.ToArray(), contentType);

If we use MemoryStream instead, disk I/O wouldn’t be used. But the problem would be occurs when excel data too large. if we use MemoryStream, and use ToArray() to get bytes[]. This would allocate too much memory from application.

Can you please consider to use StreamWriter to write stream async? C# MVC action return File() would wait StreamWriter finished. There is a sample below:

In any controller:

        private static StreamWriter sw;
        public async Task<IActionResult> Excel()
        {
            var ms = new MemoryStream();
            if (sw == null)
            {
                sw = new StreamWriter(ms);
            }
            sw.WriteLine("Sync Write");
            await sw.WriteLineAsync("Async Write");
            await sw.FlushAsync();
            await WriteAsync(sw, ms);
            ms.Position = 0;
            var extensionProvider = new FileExtensionContentTypeProvider();
            if (!extensionProvider.TryGetContentType(".txt", out string contentType))
            {
                contentType = "application/octet-stream";
            }
            return File(ms, contentType);
        }

        private async Task WriteAsync(StreamWriter sw, MemoryStream ms)
        {
            
            Thread.Sleep(5000);
            await sw.WriteLineAsync("Large bytes to write");
            await sw.FlushAsync();
        }

You can define StreamWriter inside of XSSFWorkbook. and provide WriteAsync(Stream ms). User only need to pass MemorySteam in and send to File(Stream fileStream, string contentType). This way can save memory and won’t easily to emit garbage collection.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
tonyquscommented, Nov 15, 2021

This sounds to be a good suggestion. I will consider that. Thank you!

0reactions
tonyquscommented, Oct 18, 2022

@goldenc What the fuck are you saying? Shame? I hope it’s because English is not your native language.

I don’t think WriteAsync really makes much difference although I totally understand what’s .NET async is. I’m a very senior dev on .NET for many years. .NET has been WITHOUT async for the past 10 years when .NET core didn’t exist.

Anyway, looks you are not a very satisfied user, I suggest you use commercial library instead. NPOI doesn’t welcome you anymore.

Read more comments on GitHub >

github_iconTop Results From Across the Web

StreamWriter fails with large amount of data
I'm using StreamWriter to pass a large amount of data (30mb+) via a WebRequest POST. It fails with the error The stream does...
Read more >
StreamWriter Class (System.IO)
Implements a TextWriter for writing characters to a stream in a particular encoding.
Read more >
C# FileStream, StreamWriter, StreamReader, TextWriter, ...
The StreamWriter class in C# is used for writing characters to a stream. It uses the TextWriter class as a base class and...
Read more >
using MemoryStream with StreamWriter : r/csharp
Write all your text/data to the memory stream (which could take time) ... StreamWriter's stream :and we trying to write lets think big...
Read more >
StreamWriter Constructor (System.IO)
StreamWriter (Stream). Initializes a new instance of the StreamWriter class for the specified stream by using UTF-8 encoding and the default buffer size....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found