Answer the question
In order to leave comments, you need to log in
How to implement backward compatibility of user data in the program?
A desktop application in c# is being developed, in which the user will be able to create and maintain their own data project. The development is iterative, with each new version, new functionality appears. Accordingly, the amount of data in the project grows, the format of the saved project also changes (more precisely, it is supplemented).
It is required to implement support for projects of old versions of the program, in particular:
1) Loading of all previous formats of the user project.
2) Saving the current project to the project of the old format.
Actually, the question is: how best to implement backward compatibility of formats, where can I read about it and are there ready-made solutions?
Answer the question
In order to leave comments, you need to log in
If the data format is only supplemented, then the solution is elementary. Let's say you have 2 classes in your project that implement reading and saving data. With each version, you just have new data and the old ones do not exactly change. Add (if not already done) in each file the version number. In the program, with each innovation, you simply make a couple more read / write classes for the new version. Then just watch the version when opening the file and use the required class for reading.
Another option is more stupid, fix the read / write class so that it ignores data unknown to it. Those. if you open a file from a newer version in an older version of the program, it will simply ignore data unknown to it.
In practice, I saw a very interesting implementation. There was a very clever arrangement of reading. True, the project was in Java.
There was a file read\write class, pseudocode:
class CReader{
public CReader(URL file);
void readData(){
someStructs;
}
void writeData(){
someStructs;
}
... другие методы
}
class CReader1 extends CReader{
@Override
void readData(){
super(); //Выполнить родительский метод
someNewStructs;
}
@Override
void writeData(){
super(); //Выполнить родительский метод
someNewStructs;
}
}
Keep the migration set from older versions to the latest. When saving an old project, make sure to convert to the latest format. Same thing when opening a project.
In such cases, you write your own VersionUpdater, which rebuilds the data storage structure, i.e. if we want to add a new field to the database, then we need to save the old information and add new information to it (for example, transfer to a new table with the added field). This approach will allow us to correctly process old data and add new ones right in the code, and in VersionUpdater we complete everything correctly.
The easiest way to do this is in XML. Then we can easily add new tags and ignore what is not included in the XML.
The binary file must be done in the manner of XML - in the form of a hierarchical structure of short streams. The most difficult thing is that this binary file does not have to run back and forth, like on a race track. To do this, at each of the levels of the hierarchy, there is one of two.
1. Request a certain sequence of codes, and then ask: do you have this code? Is there this one? Something like (for simplicity, I write as in C ++) ...
BlockReader blk;
int order1[] = { opHeader, opSettings, dirData };
BlockOrder order(blk, order1);
order.require(opHeader);
// считать заголовок
author = blk.readString();
if (order.get(opSettings) {
// считать настройки
}
order.require(dirData);
blk.enterDir();
// считать данные таким же образом — там может быть свой BlockOrder
blk.leaveDir();
while (blk.getBlock()) {
switch (blk.opcode) {
case dirTiledLevel:
// считать плиточный уровень
case dirGraphicLevel:
// считать уровень с фоном — цельной картинкой
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question