2010-01-21 36 views
11

Tôi mở một luồng và sau đó deserialize dữ liệu trong luồng. Tuy nhiên, tôi đã thêm một thành viên vào đối tượng SavedEventSet vì vậy bây giờ khi tôi cố mở một tệp cũ, nó ném ngoại lệ trên dòng deserialization.Đóng một luồng sau một ngoại lệ

Điều này là tốt với tôi (hiện tại) nhưng vấn đề là tôi xử lý ngoại lệ, nhưng không bao giờ đóng luồng (vì ngoại lệ xảy ra trước khi tôi đóng luồng), vì vậy khi tôi cố mở lại tệp, nó sẽ không cho tôi bởi vì nó đang được sử dụng.

Làm cách nào để đóng luồng sau ngoại lệ này? Nếu tôi đặt stream.Close() trong một trong hai catch hoặc cuối cùng, nó phàn nàn về việc cố gắng truy cập một biến cục bộ chưa được gán. Có vẻ như thực tế xấu để chỉ cần mở một tập tin ngẫu nhiên tôi biết là có. Có cách nào để mở một luồng theo cách tương tự như một hàm tạo rỗng không, vì vậy nó sẽ trông giống như nó được gán?

Cảm ơn

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*/ 
} 

Trả lời

26

Bạn có thể sử dụng một khối using, mà sẽ tự động đóng dòng, thậm chí nếu có một ngoại lệ:

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

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

+1 cho 'using()'. Đằng sau hậu trường nó biên dịch xuống một khối try/catch, và đảm bảo 'Dispose()' được gọi - nó có thể được sử dụng trên tất cả những người thực thi 'IDisposable' – STW

+0

Tôi đồng ý, đây chính xác là những gì mà 'sử dụng' . – auujay

+0

Cảm ơn :) Tôi thậm chí không biết về khối sử dụng. – EatATaco

6

Set suối để null trước khi khối try.

Trong kiểm tra lỗi của bạn nếu luồng không phải là null, nếu không thì hãy đóng luồng.

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

Tôi không hiểu tại sao nó không chỉ là không bắt đầu. Nhưng điều đó có hiệu quả, cảm ơn :) – EatATaco

+0

Tôi nghĩ giá trị mặc định là null, tức là bạn có thể gán null một cách rõ ràng chỉ để tránh cảnh báo trình biên dịch có thể xảy ra. – i486

4

Sử dụng một khối finally, điều này sẽ thực hiện cho dù một ngoại lệ xảy ra hay không:

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

Điều này thực sự không hoạt động. Tôi nhận được cùng một vấn đề "biến địa phương chưa được gán". – EatATaco

+0

Tôi cũng thích tùy chọn này, nhưng để nó hoạt động, bạn cần luồng được đặt bên ngoài khối try/catch/finally. –

+0

@Wagner Silveira - anh ấy đã tạo ra nó bên ngoài khối. – 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*/ 
} 
Các vấn đề liên quan