Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a Stream from a method, knowing it should be disposed?

I have a method that takes FileStream as input. This method is running inside a for loop.

private void UploadFile(FileStream fileStream) {     var stream = GetFileStream();     // do things with stream } 

I have another method which creates and returns the FileStream:

private FileStream GetFileStream() {     using(FileStream fileStream = File.Open(myFile, FileMode.Open))     {         //Do something         return fileStream;     } } 

Now the first method throws an ObjectDisposedException when I try to access the returned FileStream, probably because it is already closed since I am using "using" to properly dispose the stream.

If I don't use "using" and instead use it as follows, then the FileStream remains open and the next iteration of the loop (operating on the same file) throws an exception telling the file is already in use:

private FileStream GetFileStream() {     FileStream fileStream = File.Open(myFile, FileMode.Open);     //Do something     return fileStream; } 

If I use a try-finally block, where I close the stream in the finally then it also throws the ObjectDisposedException.

How to effectively return file stream and close it?

like image 801
Frank Martin Avatar asked Aug 17 '15 19:08

Frank Martin


People also ask

How do I return a stream file?

To return a file stream, you can use a FileStreamResult. This lets you specify the stream, the MIME type, and some other options (like the file name). // the stream when the transfer is complete.

How do you dispose of a stream?

If your stream is using an operating system handle to communicate with its source, consider using a subclass of SafeHandle for this purpose. This method is called by the public Dispose method and the Finalize method. Dispose invokes the protected Dispose method with the disposing parameter set to true .


1 Answers

When you return an IDisposable from a method, you are relegating the responsibility of disposing it to your caller. Thus, you need to declare your using block around the entire usage of the stream, which in your case presumably spans the UploadFile call.

using (var s = GetFileStream())     UploadFile(s); 
like image 126
Douglas Avatar answered Sep 28 '22 20:09

Douglas