《UNIXLinux程序设计教程》一2.9 临时文件

简介: 本节书摘来自华章出版社《UNIXLinux程序设计教程》一 书中的第2章,第2.9节,作者:赵克佳 沈志宇,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.9 临时文件

应用常常需要使用临时文件来暂存数据,例如,编译程序在编译器和汇编器之间交换编译结果就常常通过临时文件来进行。这种临时文件有两个特点:允许其他用户或进程读写并且名字必须唯一。前一特点要求将它们保存在公共目录中,以便任何用户读写,UNIX系统为此提供了一个专用的公共目录/tmp。后一特点是为了防止其他进程在相同目录中创建同名文件而引起冲突。UNIX系统给应用提供了专门的临时文件命名和临时文件创建函数,以保证临时文件名的唯一性。
唯一的文件名可以通过函数tmpnam()和tempnam()而获得:

#include <stdio.h>

char *tmpnam(char *s);
char *tempnam(const char *dir, const char *pfx);

tmpnam()返回一个合法的临时文件名,此文件名的目录由中定义的宏变量P_tmpdir指定,P_tmpdir通常就是/tmp。如果参数s不是空指针,tmpnam()存储该临时文件名于s指出的字符串中,此时s指向的字符串大小应当至少不小于宏常数L_tmpnam。若s为空指针,返回值指向的字符串是由tmpnam()静态分配的,将被下一次调用tmpnam()所覆盖。在同一个进程内,tmpnam()至多可以调用TMP_MAX次,并且每一次调用生成的临时文件名各不相同。
tempnam()的功能比tmpnam()的功能还要多一点,因此名字中多一个字母“e”。它可以指定临时文件存放的目录以及文件名的前缀。dir参数给出目录的路径,pfx参数给出文件名前缀。
tempnam()依次测试下述条件来确定目录路径名:
如果定义了环境变量TMPDIR,用它的值作为目录,即它可以覆盖dir参数。
如果dir参数指向一个合法的目录字符串,用它作为目录。
如果dir参数是空指针或者指向一个非法目录路径名,使用宏变量P_tmpdir 定义的目录。
如果P_tmpdir 定义的目录不可访问,使用实现定义的目录,通常是“/tmp”。
有许多应用喜欢以某种开头字符序列来命名临时文件名,pfx参数较适合这些应用。这个参数可以是空指针,也可以指向至多5个字符的一个字符串。
tempnam()存放文件名的存储空间是用malloc()分配的,当不再需要时,应当调用free()来释放它们。
tmpnam()和tempnam()仅仅根据系统当时的情况命名一个新的临时文件名,并不实际创建文件。创建和删除临时文件都是应用自己的事情。在获得文件名和文件被实际创建的这段时间内,其他进程有可能会创建同名文件,因此不建议用它们。
函数tmpfile()能避免这种竞争条件的出现,它在命名临时文件的同时也打开它。

#include <stdio.h>

FILE *tmpfile(void);

tmpfile()以读/写方式(w+)创建一个唯一的临时文件,并返回文件指针。该临时文件在进程结束时将自动删除。C标准没有规定文件的目录,Linux默认情况下为/tmp,否则为宏变量P_tmpdir指定的目录。
例2-10 程序2-10展示了上述三个函数的用法。它先调用tmpnam(),然后用存在和不存在的路径名分别调用tempname()来查看这两个函数生成的临时文件名。最后,调用tmpfile()创建一个临时文件并向其中写入一行数据,然后反绕这个文件将数据输出到标准输出验证这个临时文件的存在。
程序2-10 创建临时文件之例

#include "ch02.h"
int main(void)
{
   FILE *tempfp;
   char tmpname[L_tmpnam],*cp;
   char line[256];
   char *pfx = "XXXXX";
   if ((cp=tmpnam(tmpname))==NULL)  // 查看tmpnam()生成的文件名
      printf("a unique name cannot be generate by tmpnam()\n");
   else
      printf("       file name get by tmpnam(): %s\n", cp);
   /* 查看tempnam()生成的文件名 */
   cp = tempnam("./", pfx);          
   printf("            by tempnam(\"./\",pfx): %s\n", cp);
   free(cp);
   cp = tempnam("/not_exist_dir/", pfx);
   printf("by tempnam(\"/not_exist_dir\",pfx): %s\n", cp);
   free(cp);
    /* 用tmpfile()创建一个临时文件 */
   if ((tempfp=tmpfile()) == NULL)
      err_exit("tmpfile error");
   printf("tmpfile() created a temporary file\n");
   /* 向临时文件写入一行数据,然后将它读出并写至标准输出进行验证 */
   fputs("One line of output\n", tempfp);
   rewind(tempfp);
   if(fgets(line, sizeof(line), tempfp) == NULL)
      err_exit("fgets error");
   fputs(line,stdout); 
   exit(0);
}
相关文章
|
6月前
|
缓存 网络协议 Unix
Linux(UNIX)五种网络I/O模型与IO多路复用
Linux(UNIX)五种网络I/O模型与IO多路复用
170 0
|
6月前
|
Unix Shell Linux
在Unix/Linux操作系统中,Shell脚本广泛用于自动化任务
在Unix/Linux操作系统中,Shell脚本广泛用于自动化任务
69 2
|
27天前
|
Unix 物联网 大数据
操作系统的演化与比较:从Unix到Linux
本文将探讨操作系统的历史发展,重点关注Unix和Linux两个主要的操作系统分支。通过分析它们的起源、设计哲学、技术特点以及在现代计算中的影响,我们可以更好地理解操作系统在计算机科学中的核心地位及其未来发展趋势。
|
3月前
|
Unix Linux 程序员
Unix:Linux的“逗趣祖师爷”与它的不凡传承
在科技长河中,Unix犹如一颗恒星,既是历史见证者也是未来的启发者。1969年,因程序员肯·汤普森想在他的PDP-7上玩“Space Travel”游戏,意外创造了Unix,以简洁优雅的代码改变了操作系统的世界。进入90年代,林纳斯·托瓦兹受Unix启发,开发了开源免费的Linux,像是Unix调皮的孙子,不仅继承其精髓还增添了开放共享的精神。Unix与Linux之间的传承,就像是智者与追蝶孩童的故事,充满了岁月的智慧与新生的活力,提醒我们科技传奇往往源于不起眼的小事。下次使用Linux时,不妨会心一笑吧!
53 0
|
3月前
|
开发框架 Unix Linux
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
LangChain 构建问题之在Unix/Linux系统上设置OpenAI API密钥如何解决
48 0
|
6月前
|
Unix Shell Linux
在Linux和类Unix系统中,Shell提供了多种命令用于用户和权限管理
在Linux和类Unix系统中,Shell提供了多种命令用于用户和权限管理
76 4
|
Unix 大数据 Linux
【Linux is not Unix】Linux前言
【Linux is not Unix】Linux前言
|
6月前
|
Oracle Ubuntu Unix
Unix与Linux区别
Unix: Unix是一个操作系统家族的名称,最早由贝尔实验室(Bell Labs)的肖像电机公司(AT&T)开发。最早的Unix版本是在1969年创建的。 Linux: Linux是由芬兰计算机科学家Linus Torvalds在1991年创建的。它是作为一个免费、开放源代码的Unix克隆而开始的。
101 1
|
6月前
|
Unix Shell Linux
在Unix/Linux Shell中,管道(`|`)和重定向
在Unix/Linux Shell中,管道(`|`)和重定向
91 1
|
6月前
|
Ubuntu Unix Linux
Unix/Linux操作系统的最强入门科普(经典)
Unix/Linux操作系统的最强入门科普(经典)
395 0