2010-01-21 11 views
11

Otwieram strumień, a następnie deserializuję dane w strumieniu. Jednak dodałem element do obiektu SavedEventSet, więc teraz, gdy próbuję otworzyć stary plik, zgłasza wyjątek w wierszu deserializacji.Zamykanie strumienia po wystąpieniu wyjątku

Jest to w porządku ze mną (na razie), ale problem polega na tym, że obsługuję wyjątek, ale nigdy nie zamykam strumienia (ponieważ wyjątek wystąpił przed zamknięciem strumienia), więc gdy spróbuję ponownie otworzyć plik, nie pozwala mi, ponieważ jest w użyciu.

Jak zamknąć strumień po tym wyjątku? Jeśli umieściłem strumień.Close() w haczyku lub w końcu, to uskarża się na próbę uzyskania dostępu do nieprzypisanej zmiennej lokalnej. Wygląda na to, że po prostu otwieram losowy plik, o którym wiem, że jest. Czy istnieje sposób na otwarcie strumienia w sposób podobny do pustego konstruktora, aby wyglądał tak, jakby był przypisany?

Dzięki

SavedEventSet sES; 
OpenFileDialog oFD = new OpenFileDialog(); 
Stream stream; 
BinaryFormatter bF; 

try 
{ 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if(oFD.FileName.Contains(".sav")) 
    { 
     stream = File.Open(oFD.FileName, FileMode.Open); 
     bF = new BinaryFormatter(); 

     sES = (SavedEventSet)bF.Deserialize(stream); 
     stream.Close(); 

    } 
} 
catch (Exception ex) 
{ 
    stream.Close(); 
    /*handle Exception*/ 
} 

Odpowiedz

26

Można użyć using blok, który będzie automatycznie zamknąć strumienia, nawet jeśli jest wyjątek:

using(Stream stream = File.Open(oFD.FileName, FileMode.Open)) 
{ 
    bF = new BinaryFormatter(); 

    sES = (SavedEventSet)bF.Deserialize(stream); 
} 
+0

+1 dla 'using()'. Za kulisami kompiluje się do bloku try/catch, i gwarantuje wywołanie funkcji "Dispose()" - może być używane na wszystkich implementatorach 'IDisposable' – STW

+0

Zgadzam się, to jest dokładnie to, co jest blokiem 'using' . – auujay

+0

Dzięki :) Nie wiedziałem nawet o użyciu bloku. – EatATaco

6

Set stream null przed blokiem try.

Podczas sprawdzania catch sprawdź, czy strumień nie jest pusty, a jeśli nie, zamknij strumień.

SavedEventSet sES; 
    OpenFileDialog oFD = new OpenFileDialog(); 
    Stream stream = null; 
    BinaryFormatter bF; 

    try 
    { 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if (oFD.FileName.Contains(".sav")) 
    { 
     stream = File.Open(oFD.FileName, FileMode.Open); 
     bF = new BinaryFormatter(); 

     sES = (SavedEventSet)bF.Deserialize(stream); 
     stream.Close(); 

    } 
    } 
    catch (Exception ex) 
    { 
    if (stream != null) 
     stream.Close(); 
    /*handle Exception*/ 
    } 
+0

ja nie rozumiem, dlaczego to nie jest po prostu zerowa zacząć. Ale zadziałało, dziękuję :) – EatATaco

+0

Myślę, że domyślną wartością jest null, tzn. Można jawnie przypisywać wartość null, aby uniknąć możliwych ostrzeżeń kompilatora. – i486

4

Użyj bloku finally, to wykonać, czy wyjątek wystąpił czy nie:

try 
{ 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if(oFD.FileName.Contains(".sav")) 
    { 
    stream = File.Open(oFD.FileName, FileMode.Open); 
    bF = new BinaryFormatter(); 

    sES = (SavedEventSet)bF.Deserialize(stream); 
    } 
} 
catch (Exception ex) 
{ 
    /*handle Exception*/ 
} 
finally 
{ 
    if (stream != null) 
    stream.Close(); 
} 
+0

To w rzeczywistości nie działa. Otrzymuję tę samą "nieprzypisaną zmienną lokalną". – EatATaco

+0

Wolałbym także tę opcję, ale aby to zadziałało, potrzebujesz strumienia, który ma być utworzony poza blokiem try/catch/finally. –

+0

@Wagner Silveira - utworzył go poza blokiem. – Oded

0
SavedEventSet sES; 
OpenFileDialog oFD = new OpenFileDialog(); 
BinaryFormatter bF; 

try 
{ 
    oFD.InitialDirectory = this.path; 
    oFD.Title = "Open Event Saved File."; 
    oFD.ShowDialog(); 

    if(oFD.FileName.Contains(".sav")) 
    { 
     using(Stream stream = File.Open(oFD.FileName, FileMode.Open)) 
     { 
      bF = new BinaryFormatter(); 

      sES = (SavedEventSet)bF.Deserialize(stream); 
      stream.Close(); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    /*handle Exception*/ 
} 
Powiązane problemy