Я должен работать старое приложение, которое использовало binaryFormatter для сериализации данных приложения в filestream (скажите в файле, названном "data.oldformat") без любого optimizazion основной класс был отмечен с атрибутом
<serializable()>public MainClass
.......
end class
и код сериализации
dim b as new binaryformatter
b.serialize(mystream,mymainclass)
В попытке оптимизировать сериализацию/десериализацию обрабатывают, я просто заставил класс реализовать интерфейс ISerializable и записал некоторые оптимизированные стандартные программы сериализации
<serializable()>public MainClass
implements ISerializable
.......
end class
Оптимизация работает действительно хорошо, но я ДОЛЖЕН найти путь к reatrive данными в старых файлах для обратной совместимости.
Как я могу сделать это??
Pierluigi
Просто попробуйте то же самое, что вы делали до сих пор.
BinaryFormatter b = new BinaryFormatter();
MainClass a = b.DeSerialize(mystream) as MainClass;
Реализация ISerializable не изменила ваш исходный класс, в основном вы только что добавили методы
поскольку вы уже реализовали интерфейс ISerializable, вы, вероятно, также уже добавили необходимый конструктор:
public MainClass(SerializationInfo info, StreamingContext context) {}
вы можете использовать info-объект, переданный конструктору, для получения данных из сериализованного файла. по умолчанию (т.е. когда не реализован ISerializable), имена полей используются в качестве идентификаторов при сериализации. так что если ваш старый класс имел поле "int x", вы можете десериализовать его, используя:
this.x = info.GetInt32("x");
для более новых версий я обычно добавляю запись "version" при сериализации, как это:
public void GetObjectData(SerializationInfo info, StreamingContext context) {
info.AddValue("version", 1);
info.AddValue("othervalues", ...);
}
при десериализации вы можете проверить эту запись версии и десериализовать соответственно:
public MainClass(SerializationInfo info, StreamingContext context) {
int version;
try {
version = info.GetInt32("version");
}
catch {
version = 0;
}
switch (version) {
case 0:
// deserialize "old format"
break;
case 1:
// deserialize "new format, version 1"
break;
default:
throw new NotSupportedException("version " + version + " is not supported.");
}
}
я не компилировал этот код, может содержать опечатки.
надеюсь, это поможет.
При сериализации ваших объектов добавьте дополнительное поле Version (это не должно добавить слишком много накладных расходов). Затем в методе GetObjectData попытайтесь сначала получить поле версии и на основании того, существует оно или нет (поймав SerializationException), выполните десериализацию старым или новым способом. При старом способе все данные будут просто сериализованы, поэтому вы сможете просто вызвать Get... для всех полей.
Ваш предыдущий код должен работать. Вы получаете исключение? Попробуйте использовать новый конструктор:
Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)