2014-02-27 1 views
1

BinaryFormatter를 사용하여 개발중인 프로그램의 상태를 직렬화하려고 시도했지만 결과 파일을 deserialize하려고 할 때 다음 오류가 발생합니다. 내 코드는 파일 이름이 유효한지 확인하기 위해 검사, 그래서 나는이 오류가 일어나고있는 방법을 이해하고 있지 않다 (이미 여기에 비슷한 질문을 많이보고 후 덧붙였다) :"빈 경로 이름이 법적으로 유효하지 않은"예외를 생성하는 이유는 무엇입니까?

System.ArgumentException
Message=Empty path name is not legal.
Source=mscorlib
StackTrace:
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
at System.Windows.Media.Imaging.BitmapDecoder.SetupDecoderFromUriOrStream(Uri uri, Stream stream, BitmapCacheOption cacheOption, Guid& clsId, Boolean& isOriginalWritable, Stream& uriStream, UnmanagedMemoryStream& unmanagedMemoryStream, SafeFileHandle& safeFilehandle)
at System.Windows.Media.Imaging.BitmapDecoder.CreateFromUriOrStream(Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, RequestCachePolicy uriCachePolicy, Boolean insertInDecoderCache)
at System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()
at System.Windows.Media.Imaging.BitmapImage.EndInit()
at StarShips.Ship..ctor(SerializationInfo info, StreamingContext ctxt) in C:\Projects\Dalek\StarShips\Ship.cs:line 387

가 여기 내 저장 방법의 어떤 처음에 파일을 생성한다 : 이리저리, 나는 거의 모든 곳에서 내 파일 시스템으로/저장/로딩을 시도했습니다

Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); 
ofd.FileName = "NewGame"; 
ofd.DefaultExt = ".sav"; 
ofd.Filter = "Save Games (.sav)|*.sav"; 
Nullable<bool> result = ofd.ShowDialog(); 
if (result == true) 
{ 
    string fileName = ofd.FileName; 
    System.Diagnostics.Debug.WriteLine(fileName); 
    IFormatter formatter = new BinaryFormatter(); 
    Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); 
    stream.Position = 0; 
    MessageBox.Show(string.Format("size: {0}, Filename: {1}", stream.Length,((FileStream)stream).Name)); 
    GameTest t = (GameTest)formatter.Deserialize(stream); // Error occurs here 
    stream.Close(); 
} 

: 여기

Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog(); 
sfd.FileName = "NewGame"; 
sfd.DefaultExt = ".sav"; 
sfd.Filter = "Save Games (.sav)|*.sav"; 
Nullable<bool> result = sfd.ShowDialog(); 
if (result == true) 
{ 
    string fileName = sfd.FileName; 
    IFormatter formatter = new BinaryFormatter(); 
    Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None); 
    GameTest t = new GameTest(); 
    t.Players = GameState.Players; 
    formatter.Serialize(stream, t); 

    MessageBox.Show(string.Format("Save Complete! Size: {0}",stream.Length)); 
    stream.Close(); 
} 

을 그리고 것은 예외를 던지고 코드입니다 m 드라이브의 루트와 심지어 프로그램의 실행 폴더에도 있습니다.
Deserialize를 실행 해 보았습니다. 그리고 오브젝트 그래프를 반복하면서 갑자기 위에서 Deserialize 호출로 돌아와서 예외를 throw합니다.
비 직렬화 직전의 messagebox는 스트림의 파일 이름이 유효 함을 보여 주므로이 메시지를받는 이유는 무엇입니까?

편집 : 디버깅하는 동안 계속 오류가 계속 발생하면 "끝내기 스트림이 파싱되기 전에 발생했습니다."라는 오류가 나타납니다. 모든 클래스를 통해 두 번 확인했는데 모든 GetObjectData 메서드는 동일한 값을 serialization 생성자에 추가하므로 스트림을 넘어서 어디에서 실행되는지 알 수 없습니다.

+1

파일 이름이 있지만 실제 경로는 어디에 있습니까? – aw04

+0

FileName에는 전체 경로가 포함됩니다 (예 : "C : \ NewGame.sav". 내 지식이 기본 직렬화에 대한 MSDN 문서뿐만 아니라이 처리하는 방법이며, de-serialization 오류를 throw하기 전에 대부분의 개체 그래프를 통해 가져옵니다. –

+0

왜 Forms.OpenFileDialog가 아닌 Win32.OpenFileDialog를 사용하고 있습니까? 반환 된 경로에 일부 비 호환성이있을 수 있습니까? –

답변

5

at StarShips.Ship..ctor(SerializationInfo info, StreamingContext ctxt)

예외 호출 스택은이 문제에 대해 완전히 잘못된 구석을 찾고 있음을 보여줍니다. 직렬화 된 데이터가 포함 된 파일의 경로라고 가정 했으므로 스택 추적은 매우 다른 이야기를합니다.

혼란스러운 경우는 .ctor은 클래스 생성자의 내부 CLR 이름입니다. 그래서 실제로 폭탄을 만드는 선박 클래스 생성자입니다. BitmapImage (Uri) 생성자를 사용하여 BitmapImage 객체를 만들려고합니다. 문제가있는 생성자에 대한 인수입니다. 아마도 비트 맵의 ​​파일 이름을 serialize하는 것을 잊었거나이 문자열이 null이거나 비어있는 것을 제대로 처리하지 않았기 때문일 수 있습니다.

Ship 생성자에 중단 점을 지정하여 코드를 단일 단계로 실행합니다. 또는 Debug + Exceptions를 사용하고 CLR 예외에 대해 Thrown 확인란을 선택하여 예외가 발생할 때 디버거가 중지되도록합니다. 또는 예외를 삼키는 코드에서 try/catch를 제거하면 문제를 진단하는 중입니다.

+0

아하! 나는 정상에 집중하고 그 부분을 놓쳤다. 셀프 노트 : 다음 번에 전체 스택 추적을 읽습니다. –

관련 문제