NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: MFC Serializace - načtení části dat z porušeného souboru

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Michal Hadraba:9.10.2023 14:49

Používám pro ukládání dat MFC Serializaci. Může se stá, že se soubor poruší, nebo je uložen jinou verzí, prostě nenačítá se vše, tak jak má. Data pak nelze načíst.
Nicméně, data se skládají z několika objektů (tříd) a v případě takovéto poruchy by bylo vhodné umět případně načíst jen to, co je v pořádku.
Je nějaká metoda na umístění nějakých kontrolních zarážek při ukládání? Při načítání by se potom na začátku načítání každého objektu zkontrolovala nějaké pevná konstanta (název objektu) a pokud by neseděla, program by část dat přeskočil a skočil na
nějakou další zarážku, od níž by opět bylo možné pokračovat v načítání.
existuje nějaký standardní algoritmus? nějaký příklad?

Zkusil jsem: Hledal jsem v dokumentaci MFC, taj možné ověřit objekt pomocí CArchive::Read­Class() a CArchive::Wri­teClass(), ale již tam není řešeno jak v případě neúspěchu skočit na "zdravá" data.

Chci docílit: Aby se při chybném uložení, ať již zaviněný chybo programu či uživatele, podařilo obnovit alespoň část dat - lepší, než ztratit komplet projekt.

 
Odpovědět
9.10.2023 14:49
Avatar
Odpovídá na JerryM
Michal Hadraba:12.10.2023 8:36

Díky,
ale toto řeší vrácení chyby serializace volající funkci. To mám celkem dobře vyřešení přes Exceptions.
Mě ale jde o to, jak v případě chyby přeskočit část "nemocného" kódu a načíst alespoň ten zdravý.
Konkrétně:
Mám několik potrubí - větev A, větev B, větev C. Pokud se někde něco po...., třeba v datech větve B, nenačte se vůbec nic. A já hledám způsob, jak v tom případě přeskočit chybná data ve větvi B a načíst větev C (větev A j v té chvíli načtená).

 
Nahoru Odpovědět
12.10.2023 8:36
Avatar
JerryM
Člen
Avatar
JerryM:12.10.2023 10:30

No já myslím, že to nejde. Musel by sis ručně udělat klasický CRC kod ke každé sub-části a i k celku. Nebo si serializaci udělat ručně, což by asi bylo nejlepší. Další možností je dávat tam soubory dvakrát. Takhle to má FAT tabulka. Když se jedna posere, opraví se to z té druhé.

 
Nahoru Odpovědět
12.10.2023 10:30
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:12.10.2023 13:01

Zpracování souboru programem, jehož verze není kompatibilní s načítací strukturou souboru, je hrubou chybou programátora.

Načítaný soubor je třeba rozdělit na X částí a tato hodnota se načte z hlavičky souboru. Každá část bude mít svůj vlastní přirozený číselný identifikátor. V programu vytvoříš spojový seznam nebo pole o počtu X. Prvkem datové struktury bude bool hodnota indikující úspěšné (1) či neúspěšné (0) načtení části souboru. Dále je v programu vytvořena proměnná uchovávající počet úspěšně načtených částí a tato proměnná je inicializovaná na 0. Pokud vymezená část souboru bude úspěšně načtena, inkrementuje se proměnná o počtu úspěšných načtených částí a do prvku na pozici přirozeného identifikátoru zapíše hodnotu 1. Při neúspěchu se zapíše 0. Postupně projdeš všechna data souboru a aktualizuješ datovou strukturu a proměnnou o počtu úspěšných načtení. Poté porovnáš hodnotu X s proměnnou úspěšných načtení. Jeli shodná, vše se načetlo tak jak má a můžeš ihned pracovat s daty. Pokud si proměnné nejsou rovny (X != success_count) pak přichází na řadu průchod datové struktury. Díky uloženým hodnotám 0 nebo 1 víš přesně, která část je v pořádku a která ne. Ty části které nejsou v pořádku buď vynecháš nebo provedeš u nich obnovu či jiný tebou stanovený úkol.

Nahoru Odpovědět
12.10.2023 13:01
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Michal Hadraba:13.10.2023 8:39

Jo jasně, to je chytrý. Nejde mi ani tak o načítání nekompatibilních verzí, ale spíš nějaké chyby dané neintegritou dat, které se stejně teda z 90% vyskytnou kvůli chybě v programu :-)
No ale jak případně skočit na další část souboru, pokud se objeví v nějaké předchozí chyba? Dokážu si představit, že na začátku budu mít u každé části uloženou délku v bytech, takže pak lze adresně skákat v souboru. Jenže při ukládání tu délku vím až na konci ukládacího procesu, jak ji pak zapsat na začátek souboru???

Editováno 13.10.2023 8:40
 
Nahoru Odpovědět
13.10.2023 8:39
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:13.10.2023 10:32

Jasný, chyby by měli být způsobeny nenadálou situací (přístupová práva, nedostatek místa, apod.). Chyby v programu se poladí. :-)

Můžeš si uchovávat délky bloků, ale je nutné je přepočítávat neboť následující bloky se se změnou bloku posouvají. Další možností je vytvořit identifikátor v souboru a ten dohledávat.

Např. soubor by mohl vypadat takto:

verze 1

#1
10

#2
Rozsah teploty
0.0
40.0

#3
Otevreno

Podle verze můžeš určit jak vypadá identifikátor, počet bloků a struktury bloku. Smyslem je vyhledávání podřetězce v řetězci. jelikož jduo za sebou, je to rychle. V programu máš dvě pole, jedno pro vrácení stavu úspěšnosti, druhé je pole ukazatelů na funkce pro danou verzi, které obsahuje adresy funkcí pro načítání bloků.

Když dojde k chybě, uložíš chybový status do pole stavu úspěšnosti, a vyhledáš další blok tak, že použiješ jeho identifikátor. Např. dojde-li k chybě ve druhém bloku, iterator s hodnotou 2, tak uložíš chybový stav (např. 2) a inkrementuješ iterátor a budeš hledat nový blok (#3). Jakmile ho v souboru najdeš, přesuneš se za identifikator a načteš data pomocí funkce jejíž identifikátor je indexem v poli ukazatelů na funkce. Přesun v souboru je tedy zajištěn vyhledáním podřetezce ve zbytku souboru.

Můžeš si sestavit funkci která Ti bude lítat v celém souboru tam kam potřebuješ. Funkce bude vracet chybový stav a přebírat parametr identifikator a ukazatel na pole ukazatelů na funkce a počet bloků v souboru pro danou verzi. :-):-) Uvnitř funkce provedeš rewind souboru, vyhledáš subřetezec #loc a aplikuješ načítání dat nepřímo pomocí funkce jejíž adresu máš v poli ukazatelů na funkce na daném indexu. Parametr počet bloků v souboru slouží pro bezpečnost a efektivitu že loc <= pocet bloku. Tedy abych nehledal blok s daným ID když ho soubor nemá. :-) Podoba funkce může být hodně variabilní, může obsahovat i ukazatel na pole úspěšně načtených bloků. Dobré je vracet 0 jako úspěch a kladnou hodnotu jako identifikátor typu chyby, kterých může být víc. Její vytvoření bude zábava, ale udělá ti dobrou službu.

Možností je spoustu, můžeš to dělat i pomocí offsetů. To pak za verzí máš seznam hodnot které pak můžeš využít pro přímý přesun na pozici a následně číst data. Když ukládáš, ukládáš postupně. verze souboru, z té program ví kolik je bloků. pak seznam offsetů a pak samotná data. Osobně bych se ale přikláněl k verzi předchozí :-), hledání podřetězce. Ale obojí bude fungovat dobře. :-)

Nahoru Odpovědět
13.10.2023 10:32
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Michal Hadraba:13.10.2023 10:36

jojo, hledání podřetězce jsme měl původně v hlavě. Jen jsem si říkal, zda neexistuj nějaké fundovanější řešení, abych nevymýšlel blbosti. Nu, ale z podstaty věci asi neexistuje.

 
Nahoru Odpovědět
13.10.2023 10:36
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Michal Hadraba
DarkCoder:13.10.2023 10:41

Jiné řešení není. Pokud se chceme dostat na pozici v souboru jehož data nejsou konzistentní, musíme podle něčeho určit tuto pozici.
Není to však nic složitého. :-)

Nahoru Odpovědět
13.10.2023 10:41
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.