2010-06-23 4 views
2

지금은 매우 좌절 문제가 발생하고 있습니다. 좀 더 쉽게하기 위해 문제를 추상화하려고 노력할 것입니다. 내 사용자 지정 개체를 한 프로세스에서 데이터베이스로 serialize하고 다른 프로세스에서 deserialize해야합니다.MemoryStream deserializing - 예기치 않은 동작

나는 두 개의 단편을 가지고 있습니다. AppToDB.dllAppFromDB.dll. 제 3의 어셈블리 - MyCustomObject.dll -이 두 어셈블리 모두에 대한 참조가 들어 있습니다. MyCustomObject.dllMarshalByRefObject까지 확장됩니다. 당신이 MemoryStream 객체를 볼 수있는 코드의 두 조각, 그래서

public OCR.Batch deserializeFromDB() 
    {    
     MemoryStream memStream = new MemoryStream(); 

     try 
     { 
      string queryString = "SELECT object FROM FCBatch"; 
      OdbcCommand command = new OdbcCommand(queryString, connection); 
      OdbcDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess); 

      // Size of the BLOB buffer. 
      int bufferSize = 100; 
      // The BLOB byte[] buffer to be filled by GetBytes. 
      byte[] outByte = new byte[bufferSize]; 
      // The bytes returned from GetBytes. 
      long retval; 
      // The starting position in the BLOB output. 
      long startIndex = 0; 

      MemoryStream dbStream = new MemoryStream(); 

      while (reader.Read()) 
      { 
       // Reset the starting byte for the new BLOB. 
       startIndex = 0; 

       // Read bytes into outByte[] and retain the number of bytes returned. 
       retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize); 

       // Continue while there are bytes beyond the size of the buffer. 
       while (retval == bufferSize) 
       { 
        dbStream.Write(outByte, 0, bufferSize); 
        dbStream.Flush(); 

        // Reposition start index to end of last buffer and fill buffer. 
        startIndex += bufferSize; 
        retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize); 
       } 

       // Write the remaining buffer. 
       dbStream.Write(outByte, 0, (int)retval); 
       dbStream.Flush(); 
      } 
      // Close the reader and the connection. 
      reader.Close(); 

      dbStream.Position = 0; 
      object temp = oBFormatter.Deserialize(dbStream); 
      MyCustomObject obj = (MyCustomObject)temp; 

      return null; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      return null; 
     } 
    } 

OK : AppFromDB.dll에서

public bool serializeToDB(MyCustomObject obj) 
    {    
     OdbcDataAdapter da = new OdbcDataAdapter(); 
     MemoryStream memStream = new MemoryStream(); 

     try 
     { 
      ObjRef marshalledObj = RemotingServices.Marshal((System.MarshalByRefObject)obj); 

      // Serialize the object; construct the desired formatter 
      IFormatter oBFormatter = new BinaryFormatter(); 

      // Try to serialize the object 
      oBFormatter.Serialize(memStream, marshalledObj); 

      // Create byte array 
      byte[] serialized = memStream.ToArray(); 

      // Build the query to write to the database 
      string queryString = 
        "INSERT INTO MyCustomObject(id, object) VALUES(?, ?)"; 
      OdbcCommand command = new OdbcCommand(queryString, connection); 
      command.Parameters.AddWithValue("id", 1); 
      command.Parameters.AddWithValue("object", serialized); 

      // Write the object byte array to the database 
      int num = command.ExecuteNonQuery(); 
    } 
    catch { } 
} 

이 코드를 실행 : 내 AppToDB.dll에서

는 다음 코드를 실행합니다. 처음에는 AppToDB이 만들어졌으며 내용을 보면 707 바이트가 들어 있습니다. 벌금. 나는 그것을 데이터베이스에 쓰고 BLOB로 저장한다. 이제 AppFromDB에서 BLOB를 검색하여 byte[] 배열에 저장합니다. 배열을 MemoryStream에 다시 쓰고 내 MemoryStream 개체에 707 바이트가 들어 있는지 확인하십시오.이 모든 것은 원본과 동일합니다. 내가 성공한 물건을 옮겼던 것 같습니다!

이제 문제는 object temp = oBFormatter.Deserialize(dbStream);입니다. 역 직렬화하려고하면 object은 투명한 프록시이므로 MyCustomObject으로 전송할 수 없습니다 !! 원본 개체를 다시 얻으려면 어떻게해야합니까? # @ &의 이름은 MemoryStream 객체를 가질 수 있습니다 ... 메모리에서 ... 직렬화 할 준비가되었습니다 ... 그리고 갑자기 Transparent Proxy가 다시 나타납니다.

실종되었습니다. 도움을 주시면 감사하겠습니다. 내가 답을 가지고있는 하나 & @ #기도합니다;

편집) 1 확인을, 나는 일들이 문제가 계속하지만) (이제 이해하기 시작 말해야한다. 내 문제 : 한쪽에 객체 (상태 포함)가 있고 데이터베이스에 저장해야하므로 다른 일에 나중에 다른 프로세스에서 사용할 수 있습니다.

제 객체는 직렬화 가능으로 표시되지 않은 타사 객체를 래핑하기 때문에 직렬화 할 수 없습니다. 그래서 내 유일한 옵션은 직렬화가 가능한 ObjRef를 반환하는 마샬링 (marshal) 인 것 같습니다. 그러나 당연히 - 일 후에 - 비 직렬화하는 객체는 참조 일 뿐이며 원래 객체는 사라졌습니다.

문제를 어떻게 해결할 수 있습니까? 더 많은 사람들이 발생해야합니다 난 그냥

편집 2 OK ... 답을 찾을 수가 없어, 나는 제 3 자 객체에 동형 내 자신의 직렬화 클래스를 작성하기 위하여려고하고있다 같아요. 그런 다음 전체 타사 객체를 실행하고 상태 정보 등을 저장/포장 한 다음 데이터베이스에 객체를 직렬화합니다. 내 유일한 옵션 인 것 같습니다.

편집 3 잠시 후이 문제로 다시 시작하십시오. 편집 2에 게시 된 솔루션이 작동하지 않더라도 실현되었습니다. 제 3 자 어셈블리가 알고있는 객체로 비 순차적으로 처리해야합니다.

+0

중복 가능성 (http://stackoverflow.com/questions/3068702/how-to-marshal-an-object-and-its- [개체와 콘텐츠 (또는 객체) 마샬링 방법] content-also-objects) – Lucero

답변

1

ObjRef은 원본 개체가 아니라 참조를 전송할 모든 정보가 포함 된 "원격 참조"를 직렬화합니다.

MSDN (중점 광산)에서 :

ObjRef를가 도달하는 방법에 대한 유형 및 클래스 개체의 마샬링되고, 정확한 위치 및 통신 관련 정보를 설명하는 정보가 포함되어 있습니다 리모팅 세분은 개체를 찾습니다. MarshalByRefObject를 구현하는 클래스 마샬링 후

, 그것을 다른 프로세스 또는 컴퓨터 아마도 , 로 채널을 통해 다른 어플리케이션 도메인 를 전송 ObjRef를 나타내는 . 대상 응용 프로그램 도메인에서 ObjRef를 deserialize 할 때 은 이고 원격 MBR 개체에 대해 투명 프록시 을 만들려면 구문 분석됩니다. 이 작업을 마샬링 해제라고합니다. (때문에 제공되는 새로운 정보의)

편집 :

이 문제를 해결하기 위해 가능한 여러 가지 방법이 있습니다. XmlSerializer

  • 를 사용하여 XML 직렬화 : 그들 모두는 내가 함께 여기에 올려 놓을 게요 제한의 그들의 자신의 세트가있다. XML 직렬화는 필드 및/또는 사용자 지정 데이터 (serialize 될 개체에 의해 ISerializable이 구현 될 때)를 serialize하는 대신 개체의 모든 공용 속성을 serialize 및 deserialize한다는 점에서 다릅니다. 따라서 타사 개체가 데이터 컨테이너 일 경우 공용 속성을 serialize하는 것이 충분하고 기본 생성자를 제공하므로이 솔루션을 사용하는 것이 좋습니다.

  • 리플렉션을 사용하여 필드를 가져 와서 직렬화하는 "저급"직렬화 코드를 작성하십시오. 이 방법은 일반적으로 응용 프로그램이 완전 신뢰로 실행되도록 요구합니다. 리플렉션을 통해 비공개 필드를 반영 및 수정하려면 일반적으로 낮은 신뢰에없는 권한이 필요합니다. 여기에 당신을 도울 수있는 몇 가지 방법은 다음과 같습니다 : 필드를 serialize하려면 FormatterServices.GetSerializableMembers(), 개체 인스턴스에서 필드 데이터를 가져 오는 FormatterServices.GetObjectData()FormatterServices.GetSafeUninitializedObject() 새 초기화되지 않은 인스턴스 (생성자가 호출되지 않음)를 생성하기 위해 deseialize 할 때 FormatterServices.PopulateObjectMembers() 새로운 인스 탄에 필드를 다시 쓰십시오. 필드에서 직렬화 가능한 단순 데이터 유형 만있는 경우 필드 데이터를 저장하는 데 사용하는 object[]을 직렬화 및 비 직렬화 할 수 있습니다.

  • 제 3 자 개체의 복제본을 수동으로 작성하는 현재 아이디어입니다. 이것은 매우 고통 스러울 수 있으며 기본적으로 XML 직렬화가 작동 할 때만 작동합니다. 속성이 sinatce에 대해 읽기 전용 인 경우이 방법으로는 멀지 않습니다.

+0

답변 해 주셔서 감사합니다.하지만 지금은 정말 실망 스럽습니다. MyCustomObject는 다른 객체와 마찬가지로 메서드 및 상태 정보를 포함하며 다른 끝에 저장하고 검색해야합니다. 어떻게해야합니까 ?? 나는 일 동안 이것을 지금 일하고 있었다 :( –