曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 7400|回复: 1
打印 上一主题 下一主题

临时文件(Temporary Files)

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-2-21 15:26:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序经常会需要以文件的形式进行存储。这可能是一次计算中所保存的中间结果或者是在关键操作前的一次文件备份。例如,一个数据库程序当它要删除记录时需要用到一个临时文件。这个文件收集数据库中要保留的条目,然后在处理的最后,这个临时文件也就变成了新的数据库,而原始的数据库就被删除掉。

大量使用临时文件也有一个隐藏的缺点。你必须小心的保证程序为临时文件选择的独一无二的文件名,如果不是则会存在问题。因为LINUX 是一个多任务系统,起他的程序也可能选择相同的文件名,所以两个就会互相产生冲突。

一个独一无二的文件名可以由 tmpnam() 函数产生:
#include <stdio.h>
char *tmpnam(char *s);

tmpnam 函数返回一个不和任何一个既存文件同名的可用文件名。如果参数 s 不是 null ,那么产生的文件名也会写向它。继续调用 tmpnam() 将覆盖原先的静态存储值,所以如果 tmpnam() 要多次调用,那使用一个字符串参数是很重要的。假设字符串至少为 L_tmpnam(通常大约为20)个字符长度,那 tmpnam() 在一个单独程序中可以被调用高达 TMP_MAX (至少几千)次,并且它能在每一次产生一个不同的文件名。

如果要马上就使用临时文件,你可以对它命名并同时使用 tmpifle() 函数打开它。这很重要,因为另外一个程序会创建一个由 tmpnam() 返回值命名的相同文件名。tmpfile() 函数完全可以避免这个问题:
#include <stdio.h>
FILE *tmpfile(void);

tmpfile() 函数返回一个指向一个特定临时文件的文件流指针。这个文件可以被打开和写(通过 fopen() 函数以 w+ 指定),当所有的和文件相关联的引用都关闭时,它会自动的被删除掉。

tmpfile 返回一个空指针和错误时设置 errno .

举例测试
#include <stdio.h>
#include <stdlib.h>

int main()
{
        char tmpname[L_tmpnam];
        char *filename;
        FILE *tmpfp;

        filename = tmpnam(tmpname);

        printf("Temporary file name is: %s\n", filename);
        tmpfp = tmpfile();

        if(tmpfp)
                printf("Opened a temporary file OK\n");
        else
                perror("tmpfile");

        exit(0);
}
编译警告
[root@localhost C]# gcc -g tmpnam.c -o tmpnam.exe
/tmp/ccvqY2y6.o: In function `main':
/root/C/tmpnam.c:10: warning: the use of `tmpnam' is dangerous, better use `mkstemp'

运行及输出
[root@localhost C]# ./tmpnam.exe
Temporary file name is: /tmp/fileDI1Csz
Opened a temporary file OK
[root@localhost C]# cat tmpnam.c

说明
程序调用 tmpnam() 为一个临时文件产生一个特定文件名。如果你想使用它,那么你需要快速的去打开它以避免另外一个程序以同样的文件名去打开它的风险。tmpfile() 函数在相同的时间内创建和打开临时文件,因此避免了这风险。事实上,GNU C 编译器可能会在编译一个带有 tmpnam() 函数的程序时给出一个警告。

tmpfile() 函数以二进制 读/写(w+b) 模式打开一个特定的临时文件。这个文件当被关闭或程序结束时被自动关闭。

UNIX 使用另外的函数 -- mktemp() 和 mkstemp() 来创建临时文件名,这两个函数 linux 也支持。你在使用它们时,需要为临时文件名指定一个模板:
#include <stdlib.h>
char *mktemp(char *template);
int mkstemp(char *template);
从给定的 template 参数 mktemp() 函数创建一个特定的文件名。这个 template 参数必须是一个有着 6 个 x 字符的结尾字符串。它返回一个指向文件名的字符串的指针或者一个空指针--加入它没有产生特定文件名的话。

mkstemp() 函数和 tmpfile() 函数类似,这里它创建和打开临时文件,其返回值为一个low-level的文件描述符。

在程序中,应该总是使用“创建并打开”函数 -- tmpfile() 和 mkstemp(),而不是 tmpnam() 和 mktemp()

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-2-21 17:23:34 | 只看该作者
tmpnam() 函数产生的仅仅是文件名而已,如果要产生相应文件,那么可以使用 open() 来产生,如下测试程序:

01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <fcntl.h>
04
05 int main()
06 {
07         char *s;
08         s = tmpnam(NULL);
09         printf("%s\\n", s);
10         open( s, O_CREAT );
11
12         return 0;
13 }

运行及输出结果(通过产生的文件名创建文件)
[root@localhost C]# ./tmpnam-2.exe
/tmp/filewifJJK
[root@localhost C]# ll /tmp/filewifJJK
-r-Sr-s--- 1 root root 0 Feb 21 17:29 /tmp/filewifJJK
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 11:34 , Processed in 0.073335 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表