Portál AbcLinuxu, 10. května 2025 22:32

Dotaz: C++ mazanie a insertovanie obsahu do súboru

5.8.2021 00:09 Tomas
C++ mazanie a insertovanie obsahu do súboru
Přečteno: 673×
Odpovědět | Admin
Ako zmazať, alebo pridať obsah na začiatok, alebo do stredu súboru?

Dajme tomu, že mám niekoľko GB súbor a do stredu chcem isnertnúť reťazec "ABC" a všetok obsah, čo je za ním by sa mal posunúť o 3 bajty. Dá sa to urobiť nejako, bez nutnosti manuálne kopírovať obsah, čo je za pridaným reťazcom? Viem, že napríklad Windows na low level úrovni neukladá bajty, súboru vždy za sebou, ale ich rozdeluje na fragmenty. Napr.:

[subor1 - začiatok][subor2][subor1 - pokračovanie]

A tie časti súborov sú nejako poprepájané, dá sa to prepájanie jednotlivých častí súborov, ovládať aj priamo z programu? A existuje niečo podobné aj pre linuxové filesystémy? Robím si úložisko objektov a rozmýšľam ako takéto situácie riešiť čo najefektívnejšie. Predpokladám že STL to asi nedokáže (STL dokáže, len prepisovanie alebo append) alebo sa mýlim? Ako niečo podobné riešia napr. databázy?
Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

Jendа avatar 5.8.2021 00:52 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Inserting a hole into a file
fallocate -o 4096 -l 4096 -i soubor 
Ale funguje to jenom na některých FS (ale třeba na ext4 jo) a asi jenom pro násobky celých bloků.
Robím si úložisko objektov a rozmýšľam ako takéto situácie riešiť čo najefektívnejšie.
Nevím, co to má přesně umět, ale tohle prostě nechceš dělat. Použij nějakou vlastní datovou strukturu (strom s pointery?) nebo SQLite As An Application File Format.
6.8.2021 22:41 Tomas
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Ahoj dík pozriem sa na to
5.8.2021 15:49 Kit
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Nejjednodušší bude asi použití nějaké databáze, protože přímo na souboru by to bylo zoufale pomalé.

Ovšem je možné a efektivní nové objekty připisovat na konec souboru s informací, kam vlastně patří.
6.8.2021 22:59 Tomas
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Embedded db práveže nechcem použiť, kôli zbytočnej veľkosti libiek a výslednej binárky. Čo sa týka rýchlosti ukladania do bináriek ...testoval som to a práve ma prekvapilo aké je to rýchle. Problém ukladania objektov a štruktúr do binárnych súborov je skôr v tom, že neoplýva vlastnosťami ako bežné databázy: https://cs.wikipedia.org/wiki/ACID Ale pri projekte, ktorý ukladá dáta zo senzorov a zapisovať tam bude len samotné zariadenie to nebude až taký veľký problém.
5.8.2021 20:30 Peter Golis | skóre: 64 | blog: Bežné záležitosti | Bratislava
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Táto otázka mi pripomína objektové úložiská. Čo má byť účel, len štúdium alebo to má byť zakomponované do nejakého produktu?
6.8.2021 23:02 Tomas
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
účel je taký, že si potrebujem ukladať dáta na ESP32, pôvodne som chcel použiť SQLite, ale výsledný elf mi narástol o vyše 600KB, čo je na zariadení ktoré má 4MB flasku dosť. Tak som sa rozhodol že skúsim ukladať dáta priamo do bináriek. Takže si napíšem nejaké vlastné úložisko. Vyskúšam ako to funguje a ak by to bolo problematické tak to prepíšem a dáta budem ukladať do externej DB ale tomu by som sa rád vyhol chcel som mať all-in-one riešenie nezávislé na "vonkajšom svete".
xkucf03 avatar 7.8.2021 00:39 xkucf03 | skóre: 49 | blog: xkucf03
Rozbalit Rozbalit vše LMDB

Ještě koukni na LMDB.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
5.8.2021 22:06 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Bez urážky, mám pocit, že si nejak štúdiu informatiky preskočil nejaké lekcie.

Videl si už magnetofónovú alebo diernu pásku? Ako z takej pásky dostaneš pásku, na ktorej je v strede niečo vložené? Bez strihania. Tá páska je stream. S prísne sekvenčným prístupom. Miesto pásky môžeš mať gramofónovú platňu - prístup už nie je sekvenčný. Môžeš sa seek-nuť rovno do stredu a tam začať čítať. Alebo prepisovať. Ale nemôžeš na tej platni niečo vložiť do stredu. Musíš urobiť novú platňu.

To, čo hovoríš o windowsoch, to rozprávaš o súborovom systéme? Väčšina súborových systémov funguje tak, že má nejakú dátovú štruktúru popisujúcu vlastnosti súboru a potom má zoznam dátových blokov. A ten zoznam dátových blokov nemusí poukazovať na bloky fyzicky uložené jeden vedľa druhého. To je pravda. Ale OS ťa nepustí k tomu, kde a ako tie bloky skutočne uložené sú. Pokiaľ si teda nejdeš písať vlastný súborový systém.

Môžeš sa posunúť o level vyššie. Mať napr. súbor S, v ktorom budeš mať zoznam mien súborov (A, B, C, ..), v ktorých máš samotné dáta. A prepísaním toho S si môžeš zaznamenať informáciu, že miesto dát v súboroch (A, B, C) máš dáta súboroch (A, D, B, C). To či je to použiteľné, silne závisí od toho, čo konkrétne robíš.
5.8.2021 23:01 Kit | skóre: 45 | Brno
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Ještě můžeš udělat jeden objekt -> jeden soubor. Vložení, změna nebo smazání bude hračka. Velmi snadno to půjde spojit při exportu.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
6.8.2021 23:06 Tomas
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Možno aj to by bolo riešenie, vyskúšam ako si tisíckami súborov poradí filesystem na ESP.
Heron avatar 7.8.2021 11:34 Heron | skóre: 53 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Ako niečo podobné riešia napr. databázy?

Obecně je to tak, že fs umí soubory pouze přepisovat a nebo appendovat na jejich konec. To, co psal Jenda v prvním komentáři, je trochu nestandardní a je to podporované pouze dvěma fs a to ještě za dalších podmínek, jako že to musí být zarovnané na hranice bloků; v diskusi se tam někdo ptal, jak je to s mmap (bez odpovědi) apod. Tj. fungovalo by to pouze na konkrétním konkrétně nastaveném fs a k tomu přizpůsobeném programu.

Databáze to mají různě. Některé pouze appendují na konec a ke každému záznamu si přidávají číslo zápisu. Tedy pouze rostou a jednou za čas je potřeba udělat kopii posledních verzí záznamů do nového souboru. Tohle je současně i nejjednodušší řešení. Čistej append pro zápis a čtení po záznamech.

Obecně se tohle řeší tak, že db má ve svém souboru data ukládaná do stránek (typicky třeba 8KB), o každé stránce ví, jestli je plná nebo prázdná. Takže nová data jdou na konec souboru a nebo na volnou stránku a při potřebě něco smazat se upraví jen daná stránka. Docela dobře se to řeší přes mmap. Výhodou je, že používaný soubor (insert, delete, update), už dál neroste (prostě má nějakou svou velikost danou jeho použitím). Pro jeho zmenšení na minimální velikost je stále potřeba zkopírovat pouze živé záznamy (vacuum - tohle musejí dělat všechny velké db, nějakou formou).

Pokud pracuješ se záznamy o jasné dané a neměnné velikosti, tak k nim zkus přidat flag, jestli je ten záznam živý nebo smazaný (nebo rovnou číslo transakce) a zkus updatovat binární soubor takto.
Heron
13.8.2021 10:17 ahoj
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin

- Pridej druhy soubor "zurnal" kam budes zapisovat vzdy na konec zmeny.

nejake zaznamy position, data

- Nebo udelej hlavni soubor strukturovany

Kazdopadne pri cteni se ti to trochu zkomplikuje a nebo se ti to zkomplikuje pri zapisu (posun vseho).

Gilhad avatar 22.8.2021 13:05 Gilhad | skóre: 20 | blog: gilhadoviny
Rozbalit Rozbalit vše Re: C++ mazanie a insertovanie obsahu do súboru
Odpovědět | | Sbalit | Link | Blokovat | Admin
Rozumne se to ovladat neda a funguje to na urovni celych sektoru. Ja bych to resil tak, ze bych do toho souboru ukladal zaznamy typu

[: |dalsi|celkova delka|aktualni delka|data na aktualni delku|pad do cele delky| :] Pricemz z praktickych duvodu by prvni zaznam byl vzdy nulove delky (a ukazoval na opravdovy zacatek, aby se dalo vkladat i dopredu snadno)

Cteni by probihalo tak, ze si najdes pozici, odkud cist (scitas aktualni delky, dokud se nedostanes prez pocatecni pozici, po kazdem nacteni skocis na dalsi), ubirani par bytu udelal jako zkraceni aktualni delky (cim naroste pad), pro vkladani naopak pouzil ten pad, pokud by slo jen o par znaku a vesly se, nebo ten zaznam rozdelil a alokoval novy na konci souboru (v nejake mezere), ktery by se vlozil do retezce. V podstate implementace haldy na disku misto v pameti.

Prace ponekud slozitejsi, ale jde si na to napsat knihovnu, moznost vkladat kamkoli cokoli, nebo naopak vypoustet a pripadne i optimalizovat vtipnym pouzitim padu (ci jejich konverzi na nove bloky)

Po nejake dobe ten soubor bude desny spagetoid, ale asi nebude problem ho jednou za cas precist v tom chaotickem poradi a zapsat znovu usporadane a s rozumnou velikosti bloku a pripadnych padu.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.