ソフトウェアの設計中に、(後の段階で再処理するために) 一部のデータを一定期間保持する必要がある場合があります。実行中のメモリ内で実行するソフトウェアもあれば、この目的のために一時ファイルを作成するソフトウェアもあります。
データを保持する一時ファイルを作成することは、ソフトウェア開発者の間で一般的な方法です。一時ファイルの作成に使用されるシステム コールがいくつかあります。ここで、なぜ一時ファイルを作成するためにシステム コールが必要なのかと考える人もいるでしょう。これの背後にある主な理由は、一意の一時ファイル名を持つことです。実行中に一時ファイルを作成するプログラムがあり、同じプログラムの複数のインスタンスが同時に実行されているとします。一時ファイルの一意性が考慮されていない場合、同じプログラムの複数のインスタンスが同じ名前の一時ファイルを作成しようとして競合が発生する可能性があります。
同じ名前のファイルが存在するかどうかを確認することで、一意性を維持できると主張する人もいるかもしれません。同意!!!!しかし、これにより、この操作を正常に実行するためにソフトウェア ロジックにかさばるコードが追加されることになります。したがって、システムがソフトウェアに対してこのようなことを実行できるいくつかの呼び出しを提供するとよいでしょう。
一時ファイルを操作するために利用できるシステム コールが多数あります:
- mkstemp()
- tmpfile()
- tempnam()
- tmpnam()
- unlink()
mkstemp、tmpfile、tempnam、および tmpnam 関数は一時ファイルの作成に使用されますが、unlink 関数は作成された一時ファイルの削除に使用されます。この記事では、mkstemp() および unlink() システム コールに焦点を当てます。
mkstemp() および unlink() システム コール
mkstemp() の署名は次のようになります:
#include <stdlib.h> int mkstemp(char *template);
このシステム コールは、一時ファイルを作成して開き、開いているファイル記述子を返します。引数「テンプレート」は、一時ファイル名を生成するために使用されます。 「template」は文字通りテンプレート名のように機能するため、「template」として渡されるバッファの最後の 6 文字には「XXXXXX」が含まれている必要があります。これらの文字はシステム コールによって置き換えられ、一時ファイル名が一意になります。
unlink() の署名は次のようになります:
#include <unistd.h> int unlink(const char *pathname);
unlink() は、ファイル システムから名前を削除します。その名前がファイルへの最後のリンクであり、ファイルを開いているプロセスがない場合、ファイルは削除され、使用していたスペースが再利用できるようになります。名前がファイルへの最後のリンクであったが、プロセスがまだファイルを開いている場合、そのファイルは、それを参照している最後のファイル記述子が閉じられるまで存在し続けます。名前がシンボリック リンクを参照している場合、そのリンクは削除されます。名前がソケット、fifo、またはデバイスを参照している場合、その名前は削除されますが、オブジェクトを開いているプロセスは引き続きそれを使用できます。
また、C プログラム内でディレクトリを操作する方法を理解するには、ディレクトリを使用した C プログラミングを参照してください。
例
mkstemp() および unlink() 呼び出しを使用して、一時ファイルを操作するための使用法を示す例を見てみましょう。
#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; }
上記の例では:
- mkstemp() 関数を使用して一時ファイルを作成し、開きます。
- この関数は、使用した名前の X をいくつかの文字で更新して、全体的な名前を一意にします。
- 作成直後に、関数 unlink() が呼び出されました。
- unlink() を呼び出してもファイルはすぐには削除されませんが、ファイルが閉じられるか、プロセスが終了するまで待機します。
- 書き込み関数により、一部のデータが一時ファイルに書き込まれます
- 読み取り機能を通じてデータが読み戻されます。
- 上記の 2 つの操作は、一時ファイルを他の通常のファイルと同様に使用してファイル操作を実行できることを示しています。
- プロセスが終了するとすぐに、ファイルは unlink() によって削除されます。
上記のプログラムの出力は次のとおりです:
# ./tempfile Temporary file [/tmp/myTmpFile-wH5sLq] created Data written to temporary file is [Hello World] Data read back from temporary file is [Hello World]
したがって、一時ファイル名テンプレートで使用した X は、実際にはいくつかのランダムな文字 (この場合は wH5sLq) に置き換えられ、一時ファイル名が一意になっていることがわかります。