有些程序需要创建一些临时文件,仅供其在运行期间使用,程序终止后即行删除。例如,很多编译器程序会在编译过程中创建临时文件。GNU C语言函数库为此而提供了一系列库函数。(之所以有“一系列”的库函数,部分原因是由于这些函数分别继承自各种UNIX实现。)
本节将介绍其中的两个函数:mkstemp()和tmpfile()。
基于调用者提供的模板,mkstemp()函数生成一个唯一文件名并打开该文件,返回一个可用于I/O调用的文件描述符。
mkstemp
#include <stdlib.h>
int mkstemp(char *template);
实例:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/epoll.h>
#include <sys/uio.h>
#include <limits.h>
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%d $$ " format "\n" \
,__func__,__LINE__ \
, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
static char *file_name = "writev.txt";
int main(int argc, char **argv)
{
int fd ;
char name[] = "/tmp/lkmao_XXXXXX";
fd = mkstemp(name);
if(fd < 0){
perror("mkstemp");
return -1;
}
DEBUG_INFO("mkstemp %s ok",name);
unlink(name);
close(fd);
return 0;
}
FILE *tmpfile(void);
tmpfile()函数会创建一个名称唯一的临时文件,并以读写方式将其打开。(打开该文件时使用了O_EXCL标志,以防一个可能性极小的冲突,即另一个进程已经创建了一个同名文件。)
#include <stdio.h>
FILE *tmpfile(void);
tmpfile()函数执行成功,将返回一个文件流供stdio库函数使用。文件流关闭后将自动删除临时文件。为达到这一目的,tmpfile()函数会在打开文件后,从内部立即调用unlink()来删除该文件名。
#include <stdio.h>
int fileno(FILE *stream);
函数 fileno 检测 stream 参数,返回它的整数形式的文件描述符。
测试代码:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/epoll.h>
#include <sys/uio.h>
#include <limits.h>
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%d $$ " format "\n" \
,__func__,__LINE__ \
, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
static char *file_name = "writev.txt";
int main(int argc, char **argv)
{
FILE* p = tmpfile();
if(p == NULL){
perror("tmpfile");
return -1;
}
int fd = fileno(p);
if(fd < 0){
perror("fileno");
return -1;
}
off_t offset = 0;
pwrite(fd,"hello tmp",sizeof("hello tmp"),offset);
char buf[100];
int len = pread(fd,buf,sizeof(buf),offset);
buf[len] = '\0';
DEBUG_INFO("buf = %s",buf);
DEBUG_INFO("after pread:offset = %ld",ftell(p));
len = read(fd,buf,sizeof(buf));
buf[len] = '\0';
DEBUG_INFO("buf = %s",buf);
DEBUG_INFO("after read:offset = %ld",ftell(p));
fclose(p);
return 0;
}
测试结果:
小结