在 Linux 中使用临时文件进行 C 语言编程
创建临时文件来保存数据是软件开发人员的一种流行做法。存在几个用于创建临时文件的系统调用。现在有人会想,为什么我们需要系统调用来创建临时文件。这背后的主要原因是拥有唯一的临时文件名。假设有一个程序在运行时创建了一个临时文件,并假设同一程序的多个实例同时运行。如果没有记住临时文件的唯一性,那么同一程序的多个实例可能会尝试创建具有相同名称的临时文件,从而导致冲突。
有许多系统调用可用于操作临时文件:
- mkstemp()
- tmpfile()
- tempnam()
- tmpnam()
- unlink()
mkstemp、tmpfile、tempnam 和 tmpnam 函数用于创建临时文件,而 unlink 函数用于删除创建的临时文件。在本文中,我们将重点关注 mkstemp() 和 unlink() 系统调用。
mkstemp() 和 unlink() 系统调用
mkstemp() 的签名如下所示:
#include <stdlib.h>
int mkstemp(char *template);
该系统调用创建并打开临时文件并返回它的打开文件描述符。参数“模板”用于生成临时文件名。由于'template' 字面上的作用类似于模板名称,因此作为'template' 传递的缓冲区的最后六个字符必须包含“XXXXXX”,因为这些字符被系统调用替换以使临时文件名唯一。
unlink() 的签名如下所示:
#include <unistd.h>
int unlink(const char *pathname);
unlink() 从文件系统中删除一个名称。如果该名称是文件的最后一个链接,并且没有进程打开该文件,则该文件将被删除,并且它正在使用的空间可供重用。如果名称是文件的最后一个链接,但任何进程仍然打开该文件,则该文件将一直存在,直到最后一个引用它的文件描述符被关闭。如果名称引用了符号链接,则删除该链接。如果名称引用了套接字、fifo 或设备,则删除它的名称,但打开对象的进程可以继续使用它。
一个例子
让我们看一个示例,我们使用 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() 不会立即删除文件,而是等待文件关闭或进程退出。
- 通过 write 函数将一些数据写入临时文件
- 通过读取功能,数据被读回。
- 以上两个操作说明临时文件可以作为任何其他普通文件进行文件操作。
- 一旦进程退出,文件就会被 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]
所以我们看到我们在临时文件名模板中使用的 Xs 实际上被一些随机字符(在本例中为 wH5sLq)替换,使临时文件名唯一。
- 点赞
- 收藏
- 关注作者
评论(0)