【发布时间】:2010-08-23 19:34:58
【问题描述】:
目前我遇到了一个非常令人沮丧的问题。我将尝试将问题抽象化以使其更容易一些。它必须在一个进程中将我的自定义对象序列化到数据库并在另一个进程中反序列化它。
我有两个组件; AppToDB.dll 和 AppFromDB.dll。我有第三个程序集 - MyCustomObject.dll - 这两个程序集都包含对它的引用。 MyCustomObject.dll 扩展了 MarshalByRefObject。
在我的AppToDB.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 { }
}
在AppFromDB.dll我执行这段代码:
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;
}
}
好的,所以在这两段代码中你都可以看到一个MemoryStream 对象。在第一个 AppToDB 创建它,如果我查看它的内容,它包含 707 个字节。美好的。我将它写入数据库并将其保存为 BLOB。现在在AppFromDB 中,我检索BLOB 并将其存储在byte[] 数组中。我再次将byte[] 数组写入MemoryStream,并看到我的MemoryStream 对象包含707 个字节,所有这些都与原始字节一样。看来我已经成功转移了对象!
现在问题在于object temp = oBFormatter.Deserialize(dbStream);。一旦我尝试反序列化,我的object 就是一个透明代理,我无法转换为MyCustomObject !!如何取回我的原始对象?如何在#@& 的名称中拥有一个 MemoryStream 对象......在内存中......准备好被序列化......突然它又是一个透明代理。
我不知所措。帮助表示赞赏。我会为有答案的人祈祷#@& ;)
编辑 1 好的,我必须说现在事情开始变得有意义了(尽管问题仍然存在)。我的问题:我在一侧有一个对象(包括状态),我需要将它存储在数据库中,以便几天后我可以在另一侧的另一个进程中使用它。
我的对象不可序列化,因为它包装了未标记为可序列化的第 3 方对象。所以我唯一的选择似乎是编组,它返回一个 ObjRef,它又是可序列化的。但当然 - 几天后 - 我反序列化的对象只是引用,而我的原始对象已经消失了。
如何解决我的问题?肯定有更多人遇到过这个问题,我似乎无法找到答案......
编辑 2 好的,我想我要编写自己的可序列化类,与第 3 方对象同构。然后运行整个第 3 方对象并存储/包装其状态信息等。然后将我的对象序列化到数据库......似乎是我唯一的选择。
编辑 3 一段时间后再次开始处理这个问题。刚刚意识到虽然在编辑 2 中发布的解决方案不起作用。我必须反序列化为第 3 方程序集知道的对象,因为它将继续对其执行操作。
【问题讨论】:
标签: c# serialization memorystream