JensB
JensB

Reputation: 6880

Returning a file in asp net core 3.0 is leaking memory

I have this method.

[HttpGet("view/{fileId}/{width}/{height}/{name}")]
public async Task<FileStreamResult> View(Guid fileId, int width, int height, string name)
{
    var fileInfo = await _fileViewer.GetImageInfo(fileId, width, height);
    FileStream f = new FileStream(fileInfo.FilePath, FileMode.Open);
    return File(f, fileInfo.MimeType);
}

Which simply returns a rezised image to the browser. It works. But as far as I can tell it leaks memory.

FileStream f is never disposed.

I can see my servers Memory being every so slowly used up.

If I add a using statement in there I get an error that the stream is closed, ie the using statement closes before the file is returned to the user.

How should this be done properly?

UPDATE 1. This:

using (FileStream f = new FileStream(fileInfo.FilePath, FileMode.Open))
{
    return File(f, fileInfo.MimeType);
}

yields

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Cannot access a closed file.'.

Upvotes: 5

Views: 1318

Answers (1)

AliReza Sabouri
AliReza Sabouri

Reputation: 5275

I suggest you use Asp.net Core file-providers instead of manually reading the files using system.IO. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/file-providers?view=aspnetcore-3.1

but if you don't want to use dependency injection and inject fileProvider to your controller, this trick should work for you :

var fileInfo = await _fileViewer.GetImageInfo(fileId, width, height);
var fileName = Path.GetFileName(fileInfo.FilePath);
IFileProvider x = new PhysicalFileProvider(Path.GetDirectoryName(fileInfo.FilePath));
IFileInfo fi =  x.GetFileInfo(fileName);
 // you can use your mime type as second argumant. (fileInfo.MimeType)
return File(fi.CreateReadStream(), MediaTypeNames.Application.Octet , fileName);

Upvotes: 1

Related Questions