Binární režim
Čteme a zapisujeme bajty, které při čtení nejsou nijak interpretovány.
Funkce pro čtení
size_t fread(void *dest, size_t element_size, size_t count, FILE *in)
Čteme count prvků, každý o velikost element_size bajtů, ze streamu in,
ukládáme je do pole na adrese dest. Vrací počet přečtených prvků, pokud
bylo čtení bez chyby, pak se count a návratová hodnota rovnají.
Je nutné myslet na to, že na adrese dest musí být naalokováno dostatek
paměti, jinak dojde k nedefinovanému chování.
Funkce pro zápis
size_t fwrite(void *src, size_t element_size, size_t count, FILE *out)
do streamu out zapise count položek, každy o velikosti element_size uložených
za sebou na adrese src. Funkce vrací počet zapsaných položek.
Můžeme také pracovat s akturální pozicí, ze které v souboru čteme. Pozice je
hodnota typu long a je to index bajtu od začátku. Aktuální pozici
můžeme získat pomocí funkce
long ftell(FILE* stream)
Aktuální pozici také můžeme nastavit pomocí funkce
int fseek(FILE *stream, long offset, int start)
kde offset je počet bajtů, o které se chceme posunout
a start určuje místo, ze kterého se chceme posunout.
Pro tento účel jsou definovány konstanty
SEEK_SET zacatek souboru
SEEK_CUR aktualni pozice
SEEK_END konec souboru
V následujícím příkladu zapíšeme obsah pole do souboru a zase je načteme.
char *filename = "tmp.xx";
// zapis do souboru
float out_array[4] = { 1.0f, 2.0f, 3.0f, 4.0f };
FILE *out = fopen(filename, "wb");
assert(out);
size_t written = fwrite(out_array, sizeof(float), 4, out);
assert(written == 4);
fclose(out);
// cteni ze souboru, od druheho prvku
FILE *in = fopen(filename, "rb");
// posuneme se o jeden float dopredu
int fail = fseek(in, sizeof(float), SEEK_SET);
assert(!fail);
float in_array[3]= { 0.0f, 0.0f, 0.0f };
size_t read = fread(in_array, sizeof(float), 3, in);
assert(read == 3);
fclose(in);
for(int i = 0; i < 3; i += 1) {
printf("%f ", in_array[i]);
}
printf("\n");
Práce s binárními soubory a čtení binárních formátů má svá specifika, musíme si dávat pozor na velikosti typů, endianitu apod.
Úkoly
-
Uvažme ukládání řetězců do souboru v binárním formátu.
Naprogramujte funkci
void append(char* string, char* filename), která na konec souboru přidá nový řetězec.Naprogramujte funkci
long search(char* string, char* filename), která prohledá soubor a pokud obsahuje záznam o daném řetězci, vrátí jeho offset od začátku souboru. Jinak vrátí -1.V souboru odpovídá řetězci jeden záznam, záznamy jsou v souboru za sebou. Jeden záznam vypadá následovně.
offset velikost vyznam -------------------------------------------------------------------------- 0 2 velikost retezce v bajtech 2 ? ulozeny retezec, chapan jako posloupnost unsigned char bez 0 na konci --------------------------------------------------------------------------