在linux下使用c语言操作临时文件

本文介绍了在GNU/Linux系统中如何使用c语言安全地操作临时文件,重点关注mkstemp和tmpfile函数的使用。mkstemp创建并打开临时文件,提供文件描述符,适用于需要手动管理文件生存期的情况,而tmpfile则适用于使用C库I/O函数且不需要长期保存临时文件的场景。同时,文章强调了临时文件管理的安全性和必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用临时文件

有时候程序需要使用临时文件,用来缓存或者向别的程序传递大量的数据。在GNU/Linux系统中,临时文件被存储在 /tmp文件夹下。当使用临时文件的时候,您需要注意以下的问题:

  • 同一个程序的多个副本可能正在(由同一个用户或不同的用户)并行运行。每个副本都应该使用不同的临时文件以避免冲突。
  • 文件权限的设置应当保证临时文件不会被未被授权的用户修改或替换,从而导致程序行为被改变。
  • 生成的临时文件名应该不可被外界预料;否则,攻击者可能会在程序检测一个文件名是否被占用与实际打开临时文件进行读写之间的间隔进行攻击。

GNU/Linux 提供了 mkstemp 和 tmpfile 两个函数以帮助您解决这些问题(以辅助使用其它一些仍需要面临这些问题的函数)。两者之间的选择取决于您对文件操作的要求:是否准备将临时文件转交给其它程序?使用UNIX I/O(open、write 之类)还是标准 C 库的 I/O(fopen、fprintf 之类)?

使用 mkstemp

函数 mkstemp 从一个文件名模板生成临时文件名,创建这个临时文件,将模式设置为仅当前用户可以访问,并且以读写权限打开这个文件。文件名模板是一个字符串,其结尾应为“XXXXXX”(六个大写字母X);mkstemp函数用其它字符替换这些X以得到一个不重复的文件名。函数返回已打开的文件描述符;可以通过 write 族的函数对它执行写入操作。 由mkstemp创建的临时文件是不会被自动删除的。是否删除、以及在何时删除这些临时文件完全取决于您。(程序员应该时刻记住及时清理临时文件,否则一旦 /tmp 文件夹被填满,系统将不可用。)如果这个临时文件只是程序内部使用而不会移交给其它程序,在创建之后立刻调用unlink是个不错的主意。这个函数会从目录中移除对应的文件项,但是文件系统中的文件是有引用计数的,因此只有当所有指向该文件的描述符都被关闭的时候,它才会被文件系统真正删除。通过这个方法,您的程序可以继续使用这个临时文件,而这个临时文件会在您关闭文件描述符的时候被清除出系统。因为Linux系统会在程序结束的时候关闭所有文件描述符,即使您的程序被异常终止,临时文件仍然会被删除。代码 2.5 中的两个函数展示了 mkstemp 的使用。这两个函数一起使用可以简化将一块内存缓冲区写入临时文件(以便释放内存或将内存挪作它用)以及从临时文件读回内容的过程。 代码 2.5 (temp_file.c)使用 mkstemp

#include <stdlib.h> 
#include <unistd.h> 

/* 用于保存 write_temp_file 创建的临时文件的句柄类型。 
   在这个实现中它是一个文件文件描述符。*/ 
typedef int temp_file_handle; 

/* 将 BUFFER 中的 LENGTH 字节内容写入临时文件。 
   临时文件会立刻被执行 unlink 操作。 
   返回指向临时文件的句柄。*/ 
temp_file_handle write_temp_file (char* buffer, size_t length) 
{ 
  /* 创建文件名和文件。XXXXXX 会被替换以生成不重复的文件名。*/ 
  char temp_filename[] = “/tmp/temp_file.XXXXXX”; 
  int fd = mkstemp (tmep_filename); 
  /* 立刻进行 unlink,从而使这个文件在我们关闭描述符的时候被删除。*/ 
  unlink (temp_filename); 
  /* 将数据的长度写入文件。*/ 
  write (fd, &length, sizeof (length)); 
  /* 现在再写入数据本身。*/ 
  write (fd, buffer, length); 
  /* 将文件描述符作为指向文件的句柄。*/ 
  return fd; 
}

/*将 write_temp_file 建立的临时文件 TEMP_FILE 中的内容读回。 
*函数返回一块新分配的缓冲区,其中包含了这些内容。调用者必须用 free 释放这*个缓冲区。LENGTH 被设置为数据的长度,以字节计。临时文件最后被删除。 
*/ 
char* read_temp_file (temp_file_handle temp_file, size_t* length) 
{ 
  char* buffer; 
  /* 句柄 TEMP_FILE 是一个指向临时文件的描述符。*/ 
  int fd = temp_file; 
  /* 回滚到文件的开始。*/ 
  lseek (fd, 0, SEEK_SET); 
  /* 读取数据的长度。*/ 
  read (fd, length, sizeof(*length)); 
  /* 分配缓冲区,然后读取数据。*/ 
  buffer = (char*) malloc (*length); 
  read (fd, buffer, *length); 
  /* 关闭文件描述符。这会导致临时文件被从系统中删除。*/ 
  close (fd); 
  return buffer; 
} 

使用tmpfile

如果您使用的是 C 库 I/O 函数,且您不需要向其它程序传递这个临时文件,您可以使用 tmpfile 函数。这个函数创建并打开一个临时文件并返回一个对应的文件指针。如前例中所示,这个临时文件已经被 unlink,因此当文件指针被关闭(通过fclose)或程序结束的时候临时文件将被自动删除。 GNU/Linux 提供了其它一些用于生成临时文件或文件名的函数,包括 mktemp、tmpnam 和 tempnam 等。不要使用这些函数,因为这些函数在可靠性和安全性方面存在不足。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值