C语言creat函数如何创建文件?

99ANYc3cd6
预计阅读时长 16 分钟
位置: 首页 C语言 正文

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

c语言 creat
(图片来源网络,侵删)

函数原型

creat() 函数的原型在 <fcntl.h> 头文件中定义:

#include <fcntl.h> // 必须包含的头文件
int creat(const char *pathname, mode_t mode);

参数说明

  1. pathname (const char *)

    • 这是一个指向以 null 结尾的字符串的指针,表示你想要创建的文件的路径。
    • 可以是相对路径(如 "./newfile.txt")或绝对路径(如 "/home/user/documents/newfile.txt")。
  2. 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() 不会自动设置执行权限,如果你需要执行权限,必须显式地 ORmode 参数中。
    • 我们会使用八进制数来表示权限,因为这样更直观:
      • 0666 (rw-rw-rw-): 所有用户都有读写权限。
      • 0755 (rwxr-xr-x): 所有者有读写执行权限,组和其他用户有读和执行权限。
    • 注意:在八进制数前必须加一个 0

返回值

  • 成功:返回一个非负整数,这个整数是一个文件描述符 (file descriptor),这是一个小的整数,内核用它来标识打开的文件,后续的 I/O 操作(如 write, read, close)都需要使用它。
  • 失败:返回 -1,并设置 errno 来指示具体的错误原因,你可以使用 perror() 函数来打印出错误信息。

功能详解

creat() 的行为非常特殊,它实际上是一个 open() 函数的特例,它的功能等价于:

c语言 creat
(图片来源网络,侵删)
open(pathname, O_WRONLY | O_CREAT | O_TRUNC, mode);

我们来分解这个等价表达式:

  1. O_WRONLY: 以只写模式打开文件。
  2. O_CREAT: 如果文件 pathname 不存在,则创建它,如果文件已存在,这个标志本身不会影响文件。
  3. O_TRUNC: 如果文件已经存在,并且成功打开,那么这个标志会截断(清空)该文件,使其长度变为 0,也就是说,creat()覆盖任何已存在的同名文件。
  4. 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; // 程序成功退出
}

编译和运行:

c语言 creat
(图片来源网络,侵删)
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()

  1. 功能更全面open() 可以通过不同的标志组合实现所有 creat() 能做的,以及更多。
    • open() 可以打开文件进行读写 (O_RDWR)。
    • open() 可以在不截断文件的情况下打开文件 (O_CREAT 单独使用)。
    • open() 可以以追加模式打开文件 (O_APPEND),这在日志记录等场景中非常有用。
  2. 更安全creat() 总是会截断已存在的文件,这可能导致意外地丢失重要数据,而 open() 提供了更精细的控制,可以避免这种风险。
  3. 更符合现代编程思想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() 提供了更安全、更灵活的方式来处理文件。

-- 展开阅读全文 --
头像
北京土特产织梦仿站怎么做?
« 上一篇 04-19
织梦为何停止更新了?
下一篇 » 04-19

相关文章

取消
微信二维码
支付宝二维码