IPC с использованием Protobuf и отображенных в память файлов C#
Я пишу проект для передачи объекта из родительского приложения в дочернее приложение. Я использую Protobuf для сериализации и десериализации данных. Я также использую непостоянный отображенный в память файл для записи при сериализации (и чтения при десериализации). Вот код:
[ProtoContract(SkipConstructor = true)]
public class Test
{
[ProtoMember(1)]
public int ID { get; private set; }
[ProtoMember(2)]
public bool TestBool { get; private set; }
[ProtoMember(3)]
public string MessageBody { get; private set; }
public Test(int id, bool testBool, string messageBody)
{
this.ID = id;
this.TestBool = testBool;
this.MessageBody = messageBody;
}
public void Serialize()
{
MemoryMappedFile mmf = MemoryMappedFile.CreateNew("testmap", 1000);
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
Serializer.SerializeWithLengthPrefix(stream, this, PrefixStyle.Base128);
stream.Flush();
}
}
public static Test Deserialize()
{
using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap"))
{
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
return Serializer.DeserializeWithLengthPrefix<Test>(stream, PrefixStyle.Base128);
}
}
}
}
//On the parent application
var msg = new SharedLibrary.Test(1234, true, "Test message hahah");
msg.Serialize();
//spawn child application
//On the child application
Test result = Test.Deserialize();
Когда я запускаю этот код, я получаю следующую ошибку (когда вызывается Serializer.Deserialize):
Возникло исключение: "ProtoBuf.ProtoException" в protobuf-net.dll Дополнительная информация: Неверное поле в исходных данных: 0 Я думаю, что эта ошибка происходит, потому что поток больше, чем фактические данные, которые он содержит. Когда поток десериализован, я думаю, что он начинает читать дальше фактических данных.
Исключение: "ProtoBuf.ProtoException" в protobuf-net.dll Дополнительная информация: не найден конструктор без параметров для Test
Однако я не уверен, что это лучший способ исправить это. Есть ли способ прочитать байты из потока до тех пор, пока не останется данных, а затем остановиться? Если нет, могу ли я решить это по-другому?
1 ответ
Я не уверен, что лучший способ это исправить
- добавить конструктор без параметров (это может быть
private
если хотите) или - добавить
SkipConstructor = true
в качестве параметров на[ProtoContract(...)]
по вашему типу
тем не мение. Есть ли способ прочитать байты из потока до тех пор, пока не останется данных, а затем остановиться?
Да, это значение по умолчанию в буферах протокола, так как самое внешнее сообщение не включает в себя маркер длины или маркер конца (он предназначен для добавления). Однако, в вашем случае, это, вероятно, не то, что вам нужно, так как после сериализации данных будет различный мусор (возможно, все нули, возможно, нет). Вы можете использовать SerializeWithLengthPrefix
а также DeserializeWithLengthPrefix
вместо. И если ваши данные только 1000 байтов, MemoryStream
все будет в порядке - не нужно использовать неуправляемую память.