C语言文件操作:标准库与系统调用实践

目录

1、C语言标准库文件操作

1.1.题目要求:

1.2.函数讲解:

fopen

函数原型

参数

常用的打开模式

返回值

fwrite函数

函数原型

参数

返回值

注意事项

fseek函数

函数原型

参数

返回值

fread函数

函数原型

参数

返回值

[fclose 函数](#fclose 函数)

函数原型

参数

返回值

1.3.代码:

2、系统调用文件操作

2.1.作业内容

2.2.函数讲解

[open 函数](#open 函数)

函数原型

参数

返回值

write函数

函数原型

参数

返回值

[read 函数](#read 函数)

[1. 函数原型](#1. 函数原型)

[2. 参数](#2. 参数)

[3. 返回值](#3. 返回值)

2.3.代码:

运行效果:

1、C语言标准库文件操作

1.1.题目要求:

1.考察fopen, fread, fwrite, fseek, fclose等函数的使用

2.要求:

2.1使用代码打开当前路径下的"bite"文件(如果文件不存在在创建文件),向文件当中写入"linux so easy!".

2.2 在从文件当中读出文件当中的内容, 打印到标准输出当中; 关闭文件流指针

1.2.函数讲解:

fopen

fopen 是 C 语言标准库中的一个函数,用于打开文件,并返回一个指向 FILE 结构的指针,该指针用于后续的文件操作。如果文件打开失败,fopen 会返回 NULL。

函数原型

|---|--------------------------------------------------------|
| | FILE *fopen(const char *filename, const char *mode); |

参数

  • filename:要打开的文件的名称(包括路径,如果文件不在当前目录下)。
  • mode:打开文件的模式,决定了文件是以只读、只写、读写、追加等哪种方式被打开。模式字符串还可以包含字符 b,表示以二进制模式打开文件(在 Windows 上很重要,因为 Windows 默认以文本模式打开文件,可能会对换行符进行转换)。

常用的打开模式

  • "r":只读模式。文件必须存在。
  • "w":只写模式。如果文件存在,其内容会被清空;如果文件不存在,会创建新文件。
  • "a":追加模式。如果文件存在,写入的数据会被追加到文件末尾;如果文件不存在,会创建新文件。
  • "r+":读写模式。文件必须存在。
  • "w+":读写模式。如果文件存在,其内容会被清空;如果文件不存在,会创建新文件。
  • "a+":读写模式。如果文件存在,写入的数据会被追加到文件末尾,同时允许读取文件;如果文件不存在,会创建新文件。

返回值

  • 成功时,返回一个指向 FILE 结构的指针,该指针用于后续的文件操作。
  • 失败时,返回 NULL,并设置全局变量 errno 以指示错误类型。

fwrite函数

fwrite 函数是 C 语言标准库中的一个函数,用于将数据从内存写入到文件中。它是文件 I/O(输入/输出)操作的一部分,常用于二进制文件的写入。

函数原型

|---|----------------------------------------------------------------------------|
| | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); |

参数

  • ptr:指向要写入文件的数据的指针。这通常是一个数组或内存块的地址。
  • size:每个数据项的大小(以字节为单位)。
  • nmemb:要写入的数据项的数量。
  • stream:指向 FILE 结构的指针,该指针标识了目标文件流。这个指针通常是通过 fopen 函数获得的。

返回值

  • 成功时,返回实际写入的数据项的数量。这个值通常与 nmemb 相同,除非在写入过程中发生了错误或到达了文件末尾(对于非阻塞 I/O 或某些特殊设备文件,这可能会发生)。
  • 失败时,返回一个小于 nmemb 的值,并且会设置全局变量 errno 以指示错误类型。然而,对于普通的文件写入操作,fwrite 通常要么成功写入所有请求的数据项,要么在遇到不可恢复的错误时返回 0。

注意事项

  • fwrite 并不保证将数据实际写入到物理存储设备上;它只是将数据写入到文件系统的缓冲区中。为了确保数据被持久化,你可能需要调用 fflush 函数来刷新输出缓冲区,或者在文件关闭后依赖操作系统的自动刷新机制。
  • 在写入二进制文件时,使用 "wb" 模式打开文件是很重要的,其中 "b" 表示二进制模式。这可以防止在某些操作系统(如 Windows)上对换行符进行不必要的转换。
  • 如果 fwrite 返回的值小于 nmemb,你应该检查 errno 来确定是否发生了错误,并采取相应的错误处理措施。

fseek函数

fseek 函数是 C 语言标准库中的一个函数,用于在文件中定位流的位置。它允许你根据指定的起始点和偏移量来移动文件内部的位置指针,从而实现对文件的随机访问。

函数原型

c复制代码

|---|---------------------------------------------------------|
| | int fseek(FILE *stream, long int offset, int whence); |

参数

  • stream:指向 FILE 结构的指针,该指针标识了目标文件流。这个指针通常是通过 fopen 函数获得的。
  • offset:要移动的字节数。整数表示正向移动,负数表示负向移动。
  • whence:指定起始位置的参数,决定了 offset 是相对于哪个位置进行移动的。它可以是以下三个常量之一:
    • SEEK_SET:文件的开头。此时 offset 应为正数或零。
    • SEEK_CUR:文件的当前位置。此时 offset 可以是正数(向前移动)或负数(向后移动)。
    • SEEK_END:文件的末尾。此时 offset 通常为负数(向前移动),因为文件末尾之后没有数据可以正向移动。

返回值

  • 成功时,返回 0。
  • 失败时,返回非零值,并设置全局变量 errno 以指示错误类型。常见的错误包括无效的流指针、无效的起始点参数,或试图移动到一个无效的文件位置(如负位置或超出文件大小的位置)。

fread函数

fread 函数是 C 语言标准库中的一个函数,用于从文件中读取数据到内存中。它是文件 I/O(输入/输出)操作的一部分,常用于二进制文件的读取。

函数原型

c

|---|---------------------------------------------------------------------|
| | size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); |

参数

  • ptr:指向内存块的指针,该内存块用于存储从文件中读取的数据。这通常是一个数组的地址。
  • size:每个数据项的大小(以字节为单位)。
  • nmemb:要读取的数据项的数量。
  • stream:指向 FILE 结构的指针,该指针标识了源文件流。这个指针通常是通过 fopen 函数获得的。

返回值

  • 成功时,返回实际读取的数据项的数量。这个值可能小于 nmemb,如果到达了文件末尾或发生了其他读取错误(尽管对于普通的文件读取操作,fread 通常要么成功读取所有请求的数据项,要么在遇到文件末尾时返回实际读取的项数,要么在发生不可恢复的错误时返回 0)。
  • 失败时(即返回 0 且不是由于到达文件末尾),返回 0,并设置全局变量 errno 以指示错误类型。

fclose 函数

是 C 语言标准库中的一个函数,用于关闭一个打开的文件流,并释放与该文件流相关的资源。它是文件 I/O(输入/输出)操作的一部分,通常在完成对文件的读写操作后调用。

函数原型

c复制代码

|---|-----------------------------|
| | int fclose(FILE *stream); |

参数

  • stream:指向 FILE 结构的指针,该指针标识了要关闭的文件流。这个指针通常是通过 fopen、freopen 或 tmpfile 函数获得的。

返回值

  • 成功时,返回 0。
  • 失败时,返回 EOF(通常定义为 -1),并设置全局变量 errno 以指示错误类型。常见的错误包括无效的流指针或底层 I/O 错误。

1.3.代码:

cpp 复制代码
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
int main() {
    // 文件指针
    FILE *file;
 
    // 要写入文件的内容
    const char *contentToWrite = "linux so easy!";
    // 分配一个缓冲区来存储从文件中读取的内容
    char buffer[256];
 
    // 2.1 打开(或创建)文件
    file = fopen("bite", "w+"); // "w+" 模式表示读写,如果文件不存在则创建
    if (file == NULL) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }
 
    // 写入内容到文件
    size_t bytesWritten = fwrite(contentToWrite, sizeof(char), strlen(contentToWrite), file);
    if (bytesWritten != strlen(contentToWrite)) {
        perror("Error writing to file");
        fclose(file);
        return EXIT_FAILURE;
    }
 
    // 将文件指针重置到文件开头,以便读取
    if (fseek(file, 0, SEEK_SET) != 0) {
        perror("Error seeking in file");
        fclose(file);
        return EXIT_FAILURE;
    }
 
    // 从文件中读取内容
    size_t bytesRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, file);
    if (ferror(file)) {
        perror("Error reading from file");
        fclose(file);
        return EXIT_FAILURE;
    }
 
    // 确保字符串以null字符结尾
    buffer[bytesRead] = '\0';
 
    // 打印读取到的内容到标准输出
    printf("Read from file: %s\n", buffer);
 
    // 关闭文件
    if (fclose(file) != 0) {
        perror("Error closing file");
        return EXIT_FAILURE;
    }
 
    return EXIT_SUCCESS;
}

2、系统调用文件操作

2.1.作业内容

1.考察open, read, write, lseek, close等函数的使用。同时理解文件描述符

2.要求:

2.1 使用代码打开当前路径下的"bite"文件(如果文件不存在在创建文件),向文件当中写入"i like linux!".

2.2 在从文件当中读出文件当中的内容, 打印到标准输出当中; 关闭文件描述符

2.2.函数讲解

open 函数

是 Unix 和类 Unix 操作系统(如 Linux 和 macOS)中用于打开和可能创建文件的系统调用或库函数。在 C 语言编程中,它通常通过 <fcntl.h> 头文件声明,并用于返回一个文件描述符,该描述符用于后续的文件操作,如读取、写入和文件定位。

函数原型

在 POSIX 标准中,open 函数的原型如下:

c复制代码

|---|-----------------------------------------------------------|
| | #include <fcntl.h> |
| | #include <sys/types.h> |
| | #include <sys/stat.h> |
| | #include <unistd.h> |
| | |
| | int open(const char *pathname, int flags, mode_t mode); |

参数

  • pathname:要打开或创建的文件的路径名。
  • flags:用于指定打开文件时的行为的一组标志。这些标志可以单独使用,也可以通过按位或(|)运算符组合使用。常见的标志包括:
    • O_RDONLY:以只读方式打开文件。
    • O_WRONLY:以只写方式打开文件。
    • O_RDWR:以读写方式打开文件。
    • O_CREAT:如果文件不存在,则创建文件。使用此标志时,必须提供 mode 参数。
    • O_TRUNC:如果文件已存在且为写模式打开,则将其长度截断为 0。
    • O_APPEND:以追加模式打开文件。写入的数据将添加到文件末尾,而不是覆盖现有数据。
    • 其他标志,如 O_EXCL(与 O_CREAT 一起使用时,如果文件已存在,则调用失败)和 O_NONBLOCK(用于非阻塞 I/O 操作)等。
  • mode:设置文件权限(当使用 O_CREAT 标志时)。这是一个 mode_t 类型的值,通常使用八进制数表示,如 0644(用户读写,组读,其他读)。

返回值

  • 成功时,open 返回一个非负的文件描述符。
  • 失败时,返回 -1,并设置全局变量 errno 以指示错误类型。

write函数

write 函数是 Unix 和类 Unix 操作系统(例如 Linux 和 macOS)中用于向文件或设备写入数据的系统调用。在 C 语言编程中,它通常通过 <unistd.h> 头文件声明,并接受一个文件描述符、一个指向要写入数据的指针以及要写入的数据量作为参数。

函数原型

c复制代码

|---|---------------------------------------------------------|
| | #include <unistd.h> |
| | |
| | ssize_t write(int fd, const void *buf, size_t count); |

参数

  • fd:要写入的文件的文件描述符,该描述符是通过 open、dup、pipe、socket 等系统调用获得的。
  • buf:指向要写入数据的缓冲区的指针。
  • count:要写入的数据的字节数。

返回值

  • 成功时,write 返回实际写入的字节数。这个值可能小于请求写入的字节数(例如,如果磁盘已满或达到了文件大小限制)。
  • 失败时,返回 -1,并设置全局变量 errno 以指示错误类型。

read 函数在不同的编程环境中具有不同的实现和用途,但通常都用于从某种数据源(如文件、套接字或内存缓冲区)读取数据。以下是关于 read 函数的一些通用信息和示例:

read 函数

在Unix和类Unix操作系统(如Linux)的C语言编程中,read 函数是一个系统调用,用于从文件描述符指向的文件或设备中读取数据。

1. 函数原型

解释

c复制代码

|---|--------------------------------------------------|
| | #include <unistd.h> |
| | |
| | ssize_t read(int fd, void *buf, size_t count); |

2. 参数
  • fd:文件描述符,表示要读取的文件或设备。
  • buf:指向缓冲区的指针,用于存储读取的数据。
  • count:要读取的字节数。
3. 返回值
  • 成功时,返回实际读取的字节数(可能小于请求的字节数,特别是在读取到文件末尾时)。
  • 失败时,返回 -1,并设置全局变量 errno 以指示错误类型。

2.3.代码:

cpp 复制代码
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 1024

int main()
{

    int fd;

    ssize_t bytesRead, bytesWritten;

    char buffer[BUFFER_SIZE];

    const char *text = "i like linux!";

    // 打开(或创建)"bite"文件,使用O_WRONLY | O_CREAT | O_TRUNC标志

    fd = open("bite", O_WRONLY | O_CREAT | O_TRUNC, 0666);

    if (fd == -1)
    {

        perror("打开文件失败");

        exit(EXIT_FAILURE);
    }

    // 写入文本到文件

    bytesWritten = write(fd, text, strlen(text));

    if (bytesWritten == -1)
    {

        perror("写入文件失败");

        close(fd);

        exit(EXIT_FAILURE);
    }

    // 关闭并重新打开文件以读取

    close(fd);

    fd = open("bite", O_RDONLY);

    if (fd == -1)
    {

        perror("重新打开文件失败");

        exit(EXIT_FAILURE);
    }

    // 读取文件内容并打印到标准输出

    bytesRead = read(fd, buffer, BUFFER_SIZE - 1);

    if (bytesRead == -1)
    {

        perror("读取文件失败");

        close(fd);

        exit(EXIT_FAILURE);
    }

    // 确保字符串以null字符结尾

    buffer[bytesRead] = '\0';

    printf("文件内容: %s\n", buffer);

    // 关闭文件

    close(fd);

    return 0;
}

运行效果:

成功,并且也成功创建了文件bite

相关推荐
律宏阔1 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔1 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴1 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千2 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei372 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei372 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei372 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
codigger2 小时前
ObjectSense:一门千行内核、把可靠性写进骨子里的面向对象脚本语言
开发语言·编程·编程语言
GeW2 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
百万蹄蹄向前冲2 小时前
双端同步!云服务器装最新Node.js v26.10全过程追踪
服务器·人工智能·node.js