Getting 'Cannot access a closed Stream' error

Easy Save 2 has been replaced by Easy Save 3, so is no longer supported.
Locked
boysiepay
Posts: 5
Joined: Sun May 17, 2015 9:57 pm

Getting 'Cannot access a closed Stream' error

Post by boysiepay »

Hi there,

I am getting the following error while trying to write something new to a file. I assume I am doing something out of order, maybe I shouldn't call Write again on the same ES2Writer after a save?
If so does that mean I need to recreate a new ES2Writer after each Writer.Save()? I am trying to use a handler class to create the Reader and Writer to decouple ES2 dependencies from unrelated areas. My problem is, the class calling the ES2 wrapper expects a reader and writer (in a struct created by the ES2 wrapper). After the file exists it's easy, just create as usual. The first time I am running into this error though. The writer needs to create the file before the reader can be created, but then the writer ends saving, which it seems kills the stream.
Does this mean I need to create 2 writers for a new file (doing it the way I am where the reader and writer gets created in the wrapper class, just getting passed a path string for the file location)?


[Exception] ObjectDisposedException: Cannot access a closed Stream.
Rethrow as ZenjectException: Error occurred while initializing IInitializable with type 'EternalLife.MapBuilderManager'
__Error.StreamIsClosed() <c95265f74fdf4905bfb0d5a4b652216c>:0

MemoryStream.WriteByte() <c95265f74fdf4905bfb0d5a4b652216c>:0

BinaryWriter.Write() <c95265f74fdf4905bfb0d5a4b652216c>:0

ES2Writer.WriteHeader() Assets/Plugins/Easy Save 2/Scripts/Writers/ES2Writer.cs:486
484: }
-->486: writer.Write((byte)ES2Keys.Key._Tag);
487: writer.Write(tag);
488: lengthPosition = writer.BaseStream.Position;

ES2Writer.Write[T]() Assets/Plugins/Easy Save 2/Scripts/Writers/ES2Writer.cs:576
574: {
575: ES2Type type = ES2TypeManager.GetES2Type(param.GetType());
-->576: WriteHeader(tag, ES2Keys.Key._Null, type, null);
577: Write<T>(param, type);
578: WriteTerminator();

MapBuilderManager.Initialize() Assets/WorldMapBuilder/Scripts/MapBuilderManager.cs:76
74: else
75: {
-->76: ESHandle.Writer.Write(_current_map_uri, _current_map_tag);
77: ESHandle.Writer.Save();
78: Debug.Log("Saved map tag: " + _current_map_tag + " as: " + _current_map_uri);

TIA,
Boysenberry
boysiepay
Posts: 5
Joined: Sun May 17, 2015 9:57 pm

Re: Getting 'Cannot access a closed Stream' error

Post by boysiepay »

I guess what would be ideal would be a way to tell if the stream is closed or not, so I can reopen it when needed.

Also, I figured out (fixed) the above with:
using (ES2Writer writer = ES2Writer.Create(uri))
{
writer.Save();
}

tied to if !ES2.Exists(uri)

But knowing whether or not the stream was closed would be very helpful to avoid the error to begin with, is there something in the API for that?

Also, I am starting to see the ES2Writer.Save as being an `atomic` action that requires a Dispose call and a new ES2Writer.Create call for the next write operation. Is that the correct way to do it? All of the examples use 'using' so it's hard to know if there is a way to Write after a Save.

Thank you!
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Getting 'Cannot access a closed Stream' error

Post by Joel »

Hi there,

Once you dispose of a Writer/Reader, you will need to open a new one, it is indeed an atomic operation as you mention.

Just to clarify, if you're using it in a using block, you can assume that the Stream is closed once control leaves the using block.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
boysiepay
Posts: 5
Joined: Sun May 17, 2015 9:57 pm

Re: Getting 'Cannot access a closed Stream' error

Post by boysiepay »

Is there any way to tell if a Writer has already been disposed of?
User avatar
Joel
Moodkie Staff
Posts: 4849
Joined: Wed Nov 07, 2012 10:32 pm

Re: Getting 'Cannot access a closed Stream' error

Post by Joel »

Hi there,

If you've called the Dispose method, or control has left the 'using' block, the writer will have been disposed. You could create a Boolean in your script which is set to true if any of these happen.

All the best,
Joel
Joel @ Moodkie Interactive
Purchase Easy Save | Contact | Guides | Docs | Getting started
Locked