creat() 是一个在类 Unix 系统(如 Linux, macOS)中用于创建新文件或准备覆盖一个已存在文件的系统调用函数,它的名字是 "create" 的简写,但拼写上少了一个 'e'。

(图片来源网络,侵删)
函数原型
creat() 函数的原型在 <fcntl.h> 头文件中定义:
#include <fcntl.h> // 必须包含的头文件 int creat(const char *pathname, mode_t mode);
参数说明
-
pathname(const char *)- 这是一个指向以 null 结尾的字符串的指针,表示你想要创建的文件的路径。
- 可以是相对路径(如
"./newfile.txt")或绝对路径(如"/home/user/documents/newfile.txt")。
-
mode(mode_t)- 这个参数用于设置新创建文件的访问权限(读、写、执行)。
- 它不是一个简单的整数,而是通过位掩码来组合的,你需要使用
<sys/stat.h>中定义的宏来设置。 - 常用的权限宏有:
S_IRUSR: 用户(文件所有者)读权限S_IWUSR: 用户(文件所有者)写权限S_IXUSR: 用户(文件所有者)执行权限S_IRGRP: 组读权限S_IWGRP: 组写权限S_IXGRP: 组执行权限S_IROTH: 其他用户读权限S_IWOTH: 其他用户写权限S_IXOTH: 其他用户执行权限
- 重要提示:
creat()不会自动设置执行权限,如果你需要执行权限,必须显式地OR进mode参数中。 - 我们会使用八进制数来表示权限,因为这样更直观:
0666(rw-rw-rw-): 所有用户都有读写权限。0755(rwxr-xr-x): 所有者有读写执行权限,组和其他用户有读和执行权限。
- 注意:在八进制数前必须加一个
0。
返回值
- 成功:返回一个非负整数,这个整数是一个文件描述符 (file descriptor),这是一个小的整数,内核用它来标识打开的文件,后续的 I/O 操作(如
write,read,close)都需要使用它。 - 失败:返回
-1,并设置errno来指示具体的错误原因,你可以使用perror()函数来打印出错误信息。
功能详解
creat() 的行为非常特殊,它实际上是一个 open() 函数的特例,它的功能等价于:

(图片来源网络,侵删)
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);
我们来分解这个等价表达式:
O_WRONLY: 以只写模式打开文件。O_CREAT: 如果文件pathname不存在,则创建它,如果文件已存在,这个标志本身不会影响文件。O_TRUNC: 如果文件已经存在,并且成功打开,那么这个标志会截断(清空)该文件,使其长度变为 0,也就是说,creat()会覆盖任何已存在的同名文件。mode: 和creat()的第二个参数一样,用于设置新文件的权限。
核心要点总结:
- 创建新文件:
pathname指定的文件不存在,creat()会创建它。 - 覆盖旧文件:
pathname指定的文件已经存在,creat()会首先将其清空(长度变为 0),然后打开它。文件中原有的所有数据都会丢失! - 只写模式:打开的文件描述符默认是只写的,你不能用它来读取文件,如果你需要读写,应该使用
open()函数并指定O_RDWR标志。
示例代码
下面是一个简单的示例,演示如何使用 creat() 创建一个文件并写入一些数据。
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h> // 用于 write() 和 close()
#include <string.h> // 用于 strlen()
int main() {
const char *filename = "my_new_file.txt";
const char *message = "Hello, world! This is a test of creat().\n";
int fd; // file descriptor
mode_t mode = 0666; // 设置权限为 rw-rw-rw-
// 1. 使用 creat() 创建文件
fd = creat(filename, mode);
// 2. 检查 creat() 是否成功
if (fd == -1) {
perror("creat() failed"); // 打印错误信息
return 1; // 返回非零表示错误
}
printf("File '%s' created successfully with file descriptor: %d\n", filename, fd);
// 3. 向文件写入数据
// write() 的返回值是实际写入的字节数
ssize_t bytes_written = write(fd, message, strlen(message));
if (bytes_written == -1) {
perror("write() failed");
close(fd); // 关闭文件描述符
return 1;
}
printf("Wrote %zd bytes to the file.\n", bytes_written);
// 4. 关闭文件描述符
if (close(fd) == -1) {
perror("close() failed");
return 1;
}
printf("File descriptor %d closed.\n", fd);
return 0; // 程序成功退出
}
编译和运行:

(图片来源网络,侵删)
gcc -o creat_example creat_example.c ./creat_example
输出:
File 'my_new_file.txt' created successfully with file descriptor: 3
Wrote 43 bytes to the file.
File descriptor 3 closed.
生成的文件 my_new_file.txt
Hello, world! This is a test of creat().
creat() vs. open() 的现代用法
在现代 C 编程中,creat() 函数已经被认为过时,强烈推荐直接使用功能更强大、更灵活的 open() 函数。
为什么推荐使用 open()?
- 功能更全面:
open()可以通过不同的标志组合实现所有creat()能做的,以及更多。open()可以打开文件进行读写 (O_RDWR)。open()可以在不截断文件的情况下打开文件 (O_CREAT单独使用)。open()可以以追加模式打开文件 (O_APPEND),这在日志记录等场景中非常有用。
- 更安全:
creat()总是会截断已存在的文件,这可能导致意外地丢失重要数据,而open()提供了更精细的控制,可以避免这种风险。 - 更符合现代编程思想:
open()是一个更基础、更通用的接口,creat()只是它众多功能中的一个特例。
用 open() 实现与 creat() 相同的功能:
如果你想用 open() 实现和上面 creat() 示例完全相同的功能(创建或覆盖文件,只写),可以这样写:
// 使用 open() 替代 creat() fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
如果你想创建一个文件,但如果文件已存在则不覆盖它,只打开它进行写入(这和 creat() 的行为不同),可以这样写:
// 如果文件不存在则创建,如果存在则打开,但不截断 fd = open(filename, O_WRONLY | O_CREAT, mode);
| 特性 | creat() |
open() |
|---|---|---|
| 主要用途 | 创建新文件或覆盖旧文件 | 打开或创建文件,提供多种模式 |
| 打开模式 | 固定为只写 (O_WRONLY) |
可配置 (O_RDONLY, O_WRONLY, O_RDWR) |
| 文件存在行为 | 总是截断 (O_TRUNC) |
可配置 (O_TRUNC, O_EXCL, 默认) |
| 灵活性 | 低,功能单一 | 高,功能强大 |
| 现代推荐度 | 低,已过时 | 高,标准做法 |
除非你在维护非常古老的代码,否则请始终使用 open() 函数,并忽略 creat() 的存在。open() 提供了更安全、更灵活的方式来处理文件。
