Někdy můžete mít při navrhování softwaru požadavek po určitou dobu uchovávat některá data (pro opětovné zpracování v pozdější fázi). Některý software to dělá v paměti, ve které běží, zatímco jiný může pro tento účel vytvořit dočasný soubor.
Vytváření dočasných souborů pro uchování dat je mezi vývojáři softwaru oblíbenou praxí. Existuje několik systémových volání, která se používají k vytváření dočasných souborů. Nyní by si jeden myslel, že proč bychom k vytvoření dočasných souborů vyžadovali systémová volání. Hlavním důvodem je mít jedinečné názvy dočasných souborů. Předpokládejme, že existuje program, který za běhu vytváří dočasný soubor, a předpokládejme, že současně běží více instancí stejného programu. Pokud se nepamatuje na jedinečnost dočasných souborů, může se několik instancí stejného programu pokusit vytvořit dočasné soubory se stejným názvem, což vede ke konfliktu.
Někdo může namítnout, že jedinečnost může být zachována kontrolou, zda soubor se stejným názvem existuje nebo ne. Souhlas!!!! To by však vedlo k přidání objemného kódu do softwarové logiky, aby byla tato operace úspěšně provedena. Takže je hezké, když systém poskytuje nějaké hovory, které mohou dělat tyto věci pro váš software.
Pro manipulaci s dočasnými soubory je k dispozici mnoho systémových volání:
- mkstemp()
- tmpfile()
- tempnam()
- tmpnam()
- odpojit()
Zatímco funkce mkstemp, tmpfile, tempnam a tmpnam se používají k vytvoření dočasného souboru, funkce unlink se používá k odstranění vytvořeného dočasného souboru. Zde v tomto článku se zaměříme na systémová volání mkstemp() a unlink().
Systémová volání mkstemp() a unlink()
Podpis mkstemp() vypadá takto:
#include <stdlib.h> int mkstemp(char *template);
Toto systémové volání vytvoří a otevře dočasný soubor a vrátí pro něj popisovač otevřeného souboru. Argument „šablona“ se používá ke generování názvu dočasného souboru. Protože ‚šablona‘ doslova funguje jako název šablony, musí posledních šest znaků vyrovnávací paměti předané jako ‚šablona‘ obsahovat „XXXXXX“, protože tyto znaky jsou nahrazeny systémovým voláním, aby byl název dočasného souboru jedinečný.
Podpis unlink() vypadá takto:
#include <unistd.h> int unlink(const char *pathname);
unlink() odstraní jméno ze systému souborů. Pokud byl tento název posledním odkazem na soubor a žádný proces nemá soubor otevřený, soubor je odstraněn a prostor, který používal, je zpřístupněn pro opětovné použití. Pokud byl název posledním odkazem na soubor, ale všechny procesy mají soubor stále otevřený, soubor zůstane v existenci, dokud nebude zavřen poslední deskriptor souboru, který na něj odkazuje. Pokud název odkazuje na symbolický odkaz, odkaz je odstraněn. Pokud název odkazuje na soket, fifo nebo zařízení, jeho název je odstraněn, ale procesy, které mají objekt otevřený, jej mohou nadále používat.
Chcete-li také porozumět tomu, jak manipulovat s adresářem v programu C, viz Programování v jazyce C s adresáři.
Příklad
Podívejme se na příklad, kde používáme volání mkstemp() a unlink() k demonstraci jejich použití pro manipulaci s dočasnými soubory.
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<errno.h> int main(void) { // buffer to hold the temporary file name char nameBuff[32]; // buffer to hold data to be written/read to/from temporary file char buffer[24]; int filedes = -1,count=0; // memset the buffers to 0 memset(nameBuff,0,sizeof(nameBuff)); memset(buffer,0,sizeof(buffer)); // Copy the relevant information in the buffers strncpy(nameBuff,"/tmp/myTmpFile-XXXXXX",21); strncpy(buffer,"Hello World",11); errno = 0; // Create the temporary file, this function will replace the 'X's filedes = mkstemp(nameBuff); // Call unlink so that whenever the file is closed or the program exits // the temporary file is deleted unlink(nameBuff); if(filedes<1) { printf("\n Creation of temp file failed with error [%s]\n",strerror(errno)); return 1; } else { printf("\n Temporary file [%s] created\n", nameBuff); } errno = 0; // Write some data to the temporary file if(-1 == write(filedes,buffer,sizeof(buffer))) { printf("\n write failed with error [%s]\n",strerror(errno)); return 1; } printf("\n Data written to temporary file is [%s]\n",buffer); // reset the buffer as it will be used in read operation now memset(buffer,0,sizeof(buffer)); errno = 0; // rewind the stream pointer to the start of temporary file if(-1 == lseek(filedes,0,SEEK_SET)) { printf("\n lseek failed with error [%s]\n",strerror(errno)); return 1; } errno=0; // read the data from temporary file if( (count =read(filedes,buffer,11)) < 11 ) { printf("\n read failed with error [%s]\n",strerror(errno)); return 1; } // Show whatever is read printf("\n Data read back from temporary file is [%s]\n",buffer); return 0; }
Ve výše uvedeném příkladu:
- Vytvořte a otevřete dočasný soubor pomocí funkce mkstemp().
- Tato funkce aktualizuje X v názvu, který jsme použili, o některé znaky, díky nimž je celkový název jedinečný.
- Hned po vytvoření byla zavolána funkce unlink().
- Volání unlink() neodstraní soubor okamžitě, ale počká na uzavření souboru nebo ukončení procesu.
- Prostřednictvím funkce zápisu jsou některá data zapsána do dočasného souboru
- Prostřednictvím funkce čtení se data přečtou zpět.
- Dvě výše uvedené operace ukazují, že dočasný soubor lze použít jako jakýkoli jiný normální soubor k provádění operací se soubory.
- Jakmile proces skončí, je soubor odstraněn pomocí unlink().
Výstup výše uvedeného programu je:
# ./tempfile Temporary file [/tmp/myTmpFile-wH5sLq] created Data written to temporary file is [Hello World] Data read back from temporary file is [Hello World]
Vidíme tedy, že X, které jsme použili v šabloně názvu dočasného souboru, byly ve skutečnosti nahrazeny některými náhodnými znaky (v tomto případě wH5sLq), díky nimž je název dočasného souboru jedinečný.