0
点赞
收藏
分享

微信扫一扫

【linuxC语言】系统调用IO文件操作

瑾谋 03-08 15:30 阅读 1

文章目录


前言

在Linux系统中,C语言通过系统调用实现对文件的输入输出(I/O)操作。系统调用提供了访问操作系统核心功能的接口,其中包括文件的创建、读取、写入和关闭等操作。这篇文章将介绍在Linux环境下,如何利用C语言进行基本的文件操作,通过系统调用实现对文件的有效管理。


一、文件描述符介绍

在Linux中,文件描述符是一个用来标识打开文件或者其他I/O资源的整数。每当你打开一个文件、网络连接或者其他的I/O资源时,Linux内核会分配一个唯一的文件描述符来标识这个资源。

文件描述符的作用很重要,因为它允许程序访问和操作打开的文件或者其他I/O资源。通过文件描述符,程序可以读取、写入、关闭以及对文件进行其他操作,比如移动文件指针。文件描述符也被用来进行进程间通信,比如通过管道或者套接字。

在Linux中,标准输入、标准输出和标准错误输出也分别有对应的文件描述符,它们分别是0、1和2。这意味着你可以把标准输出重定向到一个文件,或者把标准错误输出发送到另一个程序,这些都是通过文件描述符来完成的。总之,文件描述符在Linux系统中扮演着非常重要的角色,是程序与文件系统和其他I/O资源进行交互的桥梁。

二、系统调用IO API介绍

在使用系统调用IO之前我们需要加上下面这些头文件:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

2.1 open函数

open函数原型如下:

int open(const char *pathname, int flags);

参数1为打开文件的位置,他可以打开文件还可以打开一个设备device
参数2为一个类似于权限设置的一个标识,他有如下取值:
O_RDONLY:只读方式打开文件。
O_WRONLY:只写方式打开文件。
O_RDWR:读写方式打开文件。
O_CREAT:如果文件不存在,则创建一个新文件。
O_TRUNC:如果文件存在,将其长度截断为0。
O_APPEND:在文件末尾追加写入数据,而不是覆盖文件内容。
O_EXCL:与 O_CREAT 一起使用,如果文件存在则返回错误。
O_NONBLOCK:以非阻塞方式打开文件。
O_SYNC:在每次写操作之后立即将数据写入磁盘,确保数据同步。
这些参数可以单独使用,也可以通过按位或 | 连接

他的返回值为文件描述符,类型为int

2.2 close函数

close用于关闭一个文件描述符
他的函数原型如下:

int close(int fd);

参数为文件描述符
close 返回 0 表示 成功 , 或者 -1 表示 有 错误 发生 .

2.3 read函数

read函数原型如下:

ssize_t read(int fd, void *buf, size_t count);

函数 read() 用于从文件描述符 fd 指定的文件中读取数据,并将读取的数据存储到 buf 指向的内存空间中,最多读取 count 字节的数据。该函数的参数和返回值如下:

fd:要读取数据的文件描述符。
buf:指向存储读取数据的缓冲区的指针。
count:要读取的最大字节数。
返回值是 ssize_t 类型,表示读取的字节数。如果读取成功,则返回实际读取的字节数;如果到达文件末尾,返回值为0;如果发生错误,返回值为-1,并设置全局变量 errno 来指示发生的错误类型。

2.4 write函数

write函数原型如下:

ssize_t write(int fd, const void *buf, size_t count);

函数 write() 用于将数据从内存中的 buf 写入到文件描述符 fd 所指定的文件中,最多写入 count 字节的数据。该函数的参数和返回值如下:

fd:要写入数据的文件描述符。
buf:指向包含要写入数据的缓冲区的指针。
count:要写入的字节数。
返回值是 ssize_t 类型,表示实际写入的字节数。如果写入成功,则返回写入的字节数;如果发生错误,返回值为-1,并设置全局变量 errno 来指示错误类型。

需要注意的是,write() 函数不保证一次性写入所有请求的字节数,它可能写入部分数据,而不是全部。在实际应用中,我们通常需要在返回值不等于请求写入的字节数时进行额外的处理。

2.5 lseek函数

lseek函数原型如下:

off_t lseek(int fd, off_t offset, int whence);

fd:要设置偏移量的文件描述符。
offset:要移动的偏移量,可以为正数、负数或零。正数表示向文件尾方向移动,负数表示向文件头方向移动,零表示从文件开头计算的绝对偏移量。
whence:指定偏移量的计算方式,可以是以下几个值之一:
SEEK_SET:偏移量相对于文件开头计算。
SEEK_CUR:偏移量相对于当前位置计算。
SEEK_END:偏移量相对于文件末尾计算。
返回值是 off_t 类型,表示设置后的文件偏移量。如果设置成功,则返回新的偏移量;如果发生错误,返回值为-1,并设置全局变量 errno 来指示错误类型。

三、示例代码

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

#define BUFFER_SIZE 1024

int main() {
    int fd;
    ssize_t bytes_written, bytes_read;
    off_t offset;
    char buffer[BUFFER_SIZE];

    // 打开文件
    fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 写入数据到文件
    const char *data_to_write = "Hello, World!";
    bytes_written = write(fd, data_to_write, strlen(data_to_write));
    if (bytes_written == -1) {
        perror("write");
        exit(EXIT_FAILURE);
    }
    printf("Bytes written: %ld\n", bytes_written);

    // 设置文件偏移量
    offset = lseek(fd, 0, SEEK_SET);
    if (offset == -1) {
        perror("lseek");
        exit(EXIT_FAILURE);
    }

    // 读取文件数据
    bytes_read = read(fd, buffer, BUFFER_SIZE);
    if (bytes_read == -1) {
        perror("read");
        exit(EXIT_FAILURE);
    }
    printf("Bytes read: %ld\n", bytes_read);
    printf("Data read: %.*s\n", (int)bytes_read, buffer);

    // 关闭文件
    if (close(fd) == -1) {
        perror("close");
        exit(EXIT_FAILURE);
    }

    return 0;
}

在这里插入图片描述


总结

通过系统调用进行文件I/O操作是Linux C编程中的关键方面。我们了解了如何使用系统调用来创建文件、读取文件内容、写入数据,并最终关闭文件。这些基本的文件操作是构建更复杂应用程序的基础。通过合理地利用系统调用,我们能够更好地掌控文件资源,实现高效、稳定的文件处理。在深入学习C语言和Linux编程的过程中,对文件I/O的理解将成为编写强大、可靠程序的不可或缺的一部分。

举报

相关推荐

0 条评论