2

I have a method that is called when a user resets his password. When it is executed, it should see if the user exists in the binary file "PlayerDetails.bin".

The code works as intended and the password is reset, but an error is thrown despite this:

An unhandled exception of type 'System.ObjectDisposedException' occurred in mscorlib.dll. Additional information: Cannot access a closed file.

public static bool ResetPassword(string username, string password)
{
    //open file for read and write
    long pos = -1;
    bool found = false;
    Player readPlayer;
    Stream st;
    try
    {
        st = File.Open("PlayerDetails.bin", FileMode.Open, FileAccess.ReadWrite);
        BinaryFormatter bf = new BinaryFormatter();

        while (st.Position < st.Length && !found)
        {
            pos = st.Position;
            readPlayer = (Player)bf.Deserialize(st);

            if (readPlayer.username.CompareTo(username) == 0)
            {
                found = true;
                readPlayer.password = password;

                st.Seek(pos, SeekOrigin.Begin);
                bf.Serialize(st, readPlayer);

                st.Close();
                st.Dispose();
            }
        }
    }
}
6
  • If your while loop is still executing after the first iteration, then it will try to access the file you closed at the end of that if-statement. Hence why you would get that error. Commented Mar 31, 2017 at 20:36
  • You could use a using block: using (BinaryWriter bf = new BinaryWriter(File.Open("PlayerDetails.bin", FileMode.Open, FileAccess.ReadWrite))) Commented Mar 31, 2017 at 20:38
  • Side note, according to MSFT, you should not call Close() on a Stream. Just call Dispose. msdn.microsoft.com/en-us/library/… Commented Mar 31, 2017 at 20:39
  • Adam, please mark dko's answer. He had the right idea before I was able to put my comment down. =) Commented Mar 31, 2017 at 20:48
  • 1
    Ahh, i did not fully understand his answer, I do now @Sven. Although I will continue to use the code outside of the while loop rather than finally. Commented Mar 31, 2017 at 20:51

1 Answer 1

3

move the st.Close(); st.Dispose() out of the while loop.

Stream st= null;

try
{
    st = File.Open("PlayerDetails.bin", FileMode.Open, FileAccess.ReadWrite);
    BinaryFormatter bf = new BinaryFormatter();

    try
    {
        while (st.Position < st.Length && !found)
        {
            pos = st.Position;
            readPlayer = (Player)bf.Deserialize(st);

            if (readPlayer.username.CompareTo(username) == 0)
            {
                found = true;
                readPlayer.password = password;

                st.Seek(pos, SeekOrigin.Begin);
                bf.Serialize(st, readPlayer);
            }
        }
    } 
    finally
    {
        if(st != null)
        {
            st.Close();
            st.Dispose();
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Have tried this, Error occurred under the close (however no error on the dispose part) , "Use of unassigned local variable 'st'"
fixed that. You should assign st = null first.
Use a using block instead, this code sample is pretty much the same that the compiler does for that statement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.