ISO C标准I/O库提供了两个函数以帮助创建临时文件。

#include <stdio.h>

char *tmpnam( char *ptr );
返回值:指向唯一路径名的指针 FILE *tmpfile( void );
返回值:若成功则返回文件指针,若出错则返回NULL

若ptr是NULL,则所产生的路径名存放在一个静态区中,指向该静态区的指针作为函数值返回。下一次调用tmpnam时,会重写该静态区(这意味着,如果我们调用此函数多次,而且想保存路径名,则我们应该保存该路径名的副本,而不是指针的副本)。如若ptr不是NULL,则认为它指向长度至少是L_tmpnam个字符的数组(常量L_tmpnam定义在头文件<stdio.h>中)。所产生的路径名存放在该数组中,ptr也作为函数值返回。

tmpfile创建一个临时二进制文件(类型wb+),在关闭该文件或程序结束时将自动删除这种文件。注意,UNIX对二进制文件不作特殊区分。

程序清单5-4 tmpnam和tmpfile函数实例

[root@localhost apue]# cat prog5-.c
#include "apue.h" int
main(void)
{
char name[L_tmpnam], line[MAXLINE];
FILE *fp; printf("%s\n", tmpnam(NULL)); /* first tmp name */ tmpnam(name); /* second tmp name */
printf("%s\n", name ); if((fp = tmpfile()) == NULL) /* create temp file */
err_sys("tmpfile error");
fputs("one line fo output \n", fp ); /* write to temp file */ rewind(fp); /* then read it back */
if(fgets(line, sizeof(line), fp) == NULL)
err_sys("fgets error");
fputs(line, stdout); /* print the line we wrote */
exit();
}

执行程序:

[root@localhost apue]# ./prog5-
/tmp/fileNu68ZQ
/tmp/fileaKBqgE
one line fo output

不要被上面的实例程序所迷惑,并不是说必须先用tmpnam产生一个路径名,然后再调用tmpfile创建临时文件。tmpfile单独使用即可创建临时文件。

tmpfile函数经常使用的标准UNIX技术是先调用tmpnam产生一个唯一的路径名,然后,用该路径名创建一个文件,并立即unlink它。

Single UNIX Specification为处理临时文件定义了另外两个函数,它们是XSI的扩展部分。其中第一个是tempnam函数。

#include <stdio.h>
char *tempnam( const char *directory, const char *prefix );
返回值:指向唯一路径名的指针

tempnam是tmpnam的一个变体,它允许调用者为所产生的路径名指定目录和前缀。对于目录有4种不同的选择,按下列顺序判断其条件是否为真,并且使用第一个为真的作为目录:

(1)如果定义了环境变量TMPDIR,则用其作为目录。

(2)如果参数directory非NULL,则用其作为目录。

(3)将<stdio.h>中的字符串P_tmpdir用作目录。

(4)将本地目录(通常是/tmp)用作目录。

如果prefix非NULL,则它应该是最多包含5个字符的字符串,用其作为文件名的头几个字符。

该函数调用malloc函数分配动态存储区,用其存放所构造的路径名。.当不再使用此路径名时就可释放此存储区。

程序清单5-5 演示tempnam函数

[root@localhost apue]# cat prog5-.c
#include "apue.h" int
main(int argc, char *argv[])
{
if(argc != )
err_quit("usage: prog5-5 <directory> <prefix>"); printf("%s\n", tempnam(argv[][] != ' ' ? argv[] : NULL,
argv[][] != ' ' ? argv[] : NULL)); exit();
}

注意,如果命令行参数(目录或前缀)中的任一个以空白开始,则将其作为null指针传送给该函数。下面显示使用该程序的各种方式。

[root@localhost apue]# ./prog5- /home/zhu TEMP        指定目录和前缀
/home/zhu/TEMPd18A3w
[root@localhost apue]# ./prog5- " " PFX 使用默认目录:P_tmpdir
/tmp/PFXj8BpNK
[root@localhost apue]# TMPDIR=/var/tmp ./prog5- /usr/tmp " " 使用环境变量:无前缀
/var/tmp/fileMpGbXZ
[root@localhost apue]# TMPDIR=/no/such/dir ./prog5- /home/zhu/test QQQ
/home/zhu/test/QQQaLZExQ 忽略无效环境目录

上述选择目录名的四个步骤按序执行,该函数也检查相应的目录名是否有意义。如果该目录并不存在(例如/no/such/dir),则跳过这一步,试探对目录名的下一次选择。

XSI定义的第二个函数是mkstemp。它类似于tmpfile,但是该函数返回的不是文件指针,而是临时文件的打开文件描述符。

#include <stdio.h>
int mkstemp( char *template );
返回值:若成功则返回文件描述符,若出错则返回-

它所返回的文件描述符可用于读、写文件。临时文件的名字是用template字符串参数选择的。该字符串是一个路径名,其最后6个字符设置为XXXXXX。该函数用于不同字符代换XXXXXX,以创建一路径名。如若mkstemp成功返回,它就会修改template字符串以反映临时文件的名字。

与tmpfile不同的是,mkstemp创建的临时文件不会自动删除。如若想从文件系统名字空间中删除该文件,则我们需要自行unlink它。

使用tmpnam和tempnam的一个不足之处是:在返回唯一路径名和应用程序用该路径名创建文件之间有一个时间窗口。在该事件窗口期间,另一个进程可能创建一个同名文件。tmpfile和mkstemp函数则不会产生此种问题,可以使用它们代替tmpnam和tempnam。

mktemp函数类似于mkstemp,只不过mktemp只构建一个适用于临时文件的名字,它没有创建一个文件,所以它也有与tmpnam和tempnam相同的不足之处。mktemp函数在Single UNIX Specification中被标记为遗留接口。Single UNIX Specification的未来版本可能将遗留接口全部删除,因此应当避免使用它。

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书的更多内容可参考:http://www.apuebook.com/

标准I/O库之临时文件的更多相关文章

  1. UNIX高级环境编程(7)标准IO函数库 - 二进制文件IO,流定位,创建临时文件和内存流

    1 二进制IO(Binary IO) 在前一篇我们了解了逐字符读写和逐行读写函数. 如果我们在读写二进制文件,希望以此读写整个文件内容,这两个函数虽然可以实现,但是明显会很麻烦且多次循环明显效率很低. ...

  2. UNIX环境高级编程---标准I/O库

    前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压 ...

  3. APUE(5)---标准I/O库 (3)

    十.定位流 #include <stdio.h> long ftell(FILE *fp); //若成功,返回当前文件位置指示:若出错,返回-1L int fseek(FILE *fp, ...

  4. UNIX环境高级编程 第5章 标准I/O库

    本章是关于C语言标准I/O库的,之所以在UNIX类系统的编程中会介绍C语言标准库,主要是因为UNIX和C之间具有密不可分的关系.由于UNIX系统存在很多实现,而每个实现都有自己的标准I/O库,为了统一 ...

  5. 标准I/O库

    前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压 ...

  6. UNIX系统高级编程——第五章-标准I/O库-总结

    基础: 标准I/O库在ANSI C中定义,可移植在不同的系统 文件指针(FILE):标准I/O库操作的不是文件描述符,而是流.FILE文件指针包含的是维护流所需的信息 通过函数fileno获取流的文件 ...

  7. 《UNIX环境高级编程》(APUE) 笔记第五章 - 标准I/O库

    5 - 标准I/O库 Github 地址 1. 标准 I/O 库作用 缓冲区分配 以优化的块长度执行 I/O 等 使用户不必担心如何选择使用正确的块长度 标准 I/O 最终都要调用第三章中的 I/O ...

  8. Linux C 文件操作,系统调用 -- open()、read() 和 标准I/O库 -- fopen()、fread()

    函数汇总: open().write().read().close() fopen().fwrite().fread().fclose() 一.什么是文件 在讲述文件操作之前,我们首先要知道什么是文件 ...

  9. Xcode6.1标准Framework静态库制作方法。工程转Framework,静态库加xib和图片。完美解决方案。

    http://www.cocoachina.com/bbs/read.php?tid-282490.html Xcode6.1标准Framework静态库制作方法.工程转Framework,静态库加x ...

随机推荐

  1. 3.5MM/2.5MM耳机插头定义

    自2009年国内手机耳机接口统一以来,现在国内销售耳机基本就3.5MM和2.5MM两种,当然也有很少BT厂家,就是不用这两种,比如使用MiniUSB等接口作为耳机接口.3.5mm耳机插头按照结构划分, ...

  2. 【Quick 3.3】资源脚本加密及热更新(二)资源加密

    [Quick 3.3]资源脚本加密及热更新(二)资源加密 注:本文基于Quick-cocos2dx-3.3版本编写 一.介绍 在前一篇文章中介绍了代码加密,加密方式是XXTEA.对于资源文件来说,同样 ...

  3. centos中忘记root密码问题

    centos中root密码问题   几次在虚拟机中安装cenos,都没有提示输入root密码,具体操作如下: 1.在启动的时候,进入启动界面后,按除了Enter键之外的任意键,即可进入该界面.然后 按 ...

  4. bzoj2749

    根绝欧拉函数的计算式,欧拉函数次方每次就是不断把2消掉,并把其他质因子不断变出2,最终弄成1显然我们先预处理每个数会被弄出多少个2出来,次方=弄出来的2的总数-[一开始是否有2](因为一开始没2的话是 ...

  5. Nagios ’status.cgi‘文件权限许可和访问控制漏洞

    漏洞名称: Nagios ’status.cgi‘文件权限许可和访问控制漏洞 CNNVD编号: CNNVD-201307-013 发布时间: 2014-02-21 更新时间: 2014-02-21 危 ...

  6. 解决Dagger2和butterknife冲突

    dagger2 和 RxJava butterknife 以及 Retrofit使用起来非常酸爽 代码非常干净清晰 动手尝试 配置编译 DaggerAppComponent的时候 出现问题 配置dag ...

  7. POJ --- 2918 求解数独

    Tudoku   Description Tom is a master in several mathematical-theoretical disciplines. He recently fo ...

  8. [King.yue]Grid列赋值文本,隐藏Value

    例:public string InputFormat 加扩展属性:public string InputFormatText 构造函数中根据Key取到Value的值: var data = Data ...

  9. Content-Type伪装 - 将jsp伪装成css

    一.前期理论准备 1)目的:  在jsp中动态生成css语句,然后输出给浏览器解析.渲染. 2)浏览器解析文件的依据:  页面加载后,浏览器会发起各个请求去下载各种资源.  比如下载css文件,然后根 ...

  10. ArrayLLis 线程不安 实验

    这段代码演示了ArrayList的线程不安全,我让3个线程分别对list加入300个字符串,最后的arr的大小为800多,大家可以测试一下,我的一次是898,一次是897,同时还学了join的用法 i ...