文件IO: 从入门到精通(二)

目录

介绍

打开文件

读取文件

写入文件

文件偏移位置

关闭文件

总结


介绍

文件I/O是操作系统中的一个基本组件。它允许我们从文件中读取数据并将数据写入到文件中。在这篇博客中,我们将详细了解一些文件I/O的概念以及如何在C程序中使用文件I/O。

文件I/O的概念 文件I/O是指读取和写入文件的操作。在操作系统中,我们通常使用标准I/O库来进行文件I/O操作。标准I/O库提供了一些函数和宏,使我们能够打开、读取、写入和关闭文件。

在文件I/O中,我们使用文件描述符来代表打开的文件。文件描述符是一个整数,它指示了操作系统内核中的文件表中打开文件的位置。每个进程都有一个文件表,其中包含当前打开的文件的信息。

文件I/O库提供了一些函数来操作文件描述符,这些函数包括打开文件、关闭文件、读取文件和写入文件。下面我们将详细介绍这些函数。

打开文件

打开一个文件意味着获取到这个文件的访问句柄(文件描述符fd,在内核管理的打开文件顺序表的下标)

功能

打开一个指定的文件并获得文件描述符,创建一个新文件

头文件

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

函数原型

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

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

参数

参数1:

        const char *pathname:指针,字符串的地址,字符串是即将打开的文件

参数2:

        int flags:打开方式

        O_RDONLY:读打开

        O_WRONLY:写打开

        O_RDWR:读写打开----三个是互斥

        O_APPEND:以追加方式打开(必须有写)

        O_CREAT:如果文件不存在,则会创建文件

                            函数需要第三个参数

                            mode参数

                            不使用,可以没有第三个参数

         O_EXCL:与O_CREAT一起使用,如果文件存在,则返回错误信息,用于只创建新文件

          O_NOCTTY:如果文件是终端文件,终端就不能作为当前打开文件的程序的控制终端

          O_TRUNC:如果文件存在,则清空文件

参数3:

         mode_t mode:文件创建的权限

         权限 == mode & ~umask

返回值

成功:返回打开文件的文件描述符(int)

失败:返回-1

备注

flags:打开方式,可以多个合用,如:有读写,追加,创建--->O_RDWR | O_APPEND | O_CREAT

mode:创建权限,以八进制表示,如:0777,0664

注意:当第二个参数中有O_CREAT时,必须加上第三个参数即文件创建权限

文件io的打开指令:

例如,以下代码将打开一个名为“example.txt”的文件,如果文件不存在,则创建该文件。

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

int main() {
    int fd = open("example.txt", O_CREAT | O_RDWR, 0644);//打开文件,存在以只读打开,不存在创建文件(文件权限为0664)
    if (fd == -1) {
        perror("open");
        return 1;
    }
    // 在此处操作文件
    close(fd);//关闭文件
    return 0;
}

在这个例子中,我们使用了open()函数来打开“example.txt”文件,以读写方式打开,并且如果文件不存在,则创建该文件。0644是文件许可模式。

读取文件

要从文件中读取数据,我们需要使用read()函数。read()函数接受三个参数,一个是文件描述符,一个是缓冲区用于存储读取的数据,另一个是要读取的字节数。

功能

从指定文件中读取数据

头文件

#include <unistd.h>

函数原型

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

参数

参数1:

        int fd:文件描述符,指定读取的文件,从fd文件中读取

参数2:

        void * buf:读取的数据存储的地址,自定义存储位置

参数3:

         size_t count:想从文件中读取对应的字节数

返回值

成功:返回实际读取的字节数,0表示当前已经读取到末尾

失败:返回-1

例如,以下代码打开一个文件,读取其中的数据并将其打印到控制台。

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

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }
    char buf[1024];
    ssize_t n = read(fd, buf, sizeof(buf)); //读取文件内容
    if (n == -1) {
        perror("read");
        close(fd);
        return 1;
    }
    printf("读取的数据是:\n%.*s\n", (int)n, buf);
    close(fd);
    return 0;
}

在这个例子中,我们打开了一个文件,然后使用read()函数从文件中读取数据。我们定义了一个缓冲区来存储读取的数据,并将其打印到控制台。

写入文件

要向文件中写入数据,我们需要使用write()函数。write()函数接受三个参数,一个是文件描述符,一个是要写入的数据的指针,另一个是要写入的字节数。

功能

往指定文件中写入数据

头文件

#include <unistd.h>

函数原型

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

参数

参数1:

        int fd:要写入的文件,往fd文件中写入

参数2:

        const void *buf:指针,要写入的数据首地址,自定义数据空间,把空间的数据写入

参数3:

         size_t count:要写入的字节数

返回值

成功:返回写入的字节数

失败:返回 -1

例如,以下代码打开了一个文件,并将一些数据写入该文件。

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

int main() {
    int fd = open("example.txt", O_WRONLY | O_APPEND);
    if (fd == -1) {
        perror("open");
        return 1;
    }
    const char* buf = "这是要写入的数据\n";
    ssize_t n = write(fd, buf, strlen(buf));//写入文件
    if (n == -1) {
        perror("write");
        close(fd);
        return 1;
    }
    close(fd);
    return 0;
}

在这个例子中,我们打开了一个文件,并使用write()函数将一些数据写入该文件。我们定义了一个字符串来存储要写入的数据,并将其写入文件中。

文件偏移位置

文件偏移位置是指文件中数据的起始位置,通常以字节为单位。在对文件进行读取或写入时,会使用文件偏移位置来确定从哪里开始读取或写入数据。文件偏移位置的初始值为0,每次读取或写入操作完成后,文件偏移位置会自动增加相应的字节数。可以使用系统调用函数lseek来改变文件偏移位置,从而实现对文件的随机读取或写入。

功能

调整设置文件位置偏移量

头文件

#include <sys/types.h>

#include <unistd.h>

函数原型

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

参数

参数1:

        int fd:要调整位置偏移量的文件描述符

参数2:

        off_t offset:新的偏移位置相对基准点的偏移量

参数3:

        int whence:基准点

                             SEEK_SET:文件开始处

                             SEEK_CUR:当前位置

                             SEEK_END:文件末尾处

返回值

成功:返回新位置距离文件开始处的偏移量

失败:返回-1

例如,以下代码打开了一个文件,并进行文件偏移。

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

int main() {
    // 打开文件
    int fd = open("example.txt", O_RDWR);
    if (fd == -1) {
        perror("open");
        return -1;
    }

    // 从文件开头偏移10个字节
    off_t offset = lseek(fd, 10, SEEK_SET);
    if (offset == -1) {
        perror("lseek");
        return -1;
    }

    // 读取文件中当前位置后的10个字节
    char buf[11];
    ssize_t n = read(fd, buf, 10);
    if (n == -1) {
        perror("read");
        return -1;
    }
    buf[n] = '\0';
    printf("Read %d bytes: %s\n", n, buf);

    // 从当前位置再偏移10个字节
    offset = lseek(fd, 10, SEEK_CUR);
    if (offset == -1) {
        perror("lseek");
        return -1;
    }

    // 写入数据到当前位置
    char *data = "Hello World";
    n = write(fd, data, 11);
    if (n == -1) {
        perror("write");
        return -1;
    }

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

    return 0;
}

在这个例子中,我们使用open函数打开了名为example.txt的文件,并将文件标识符存储在变量fd中。然后,我们使用lseek函数将文件偏移位置从文件开头移动10个字节。接下来,我们使用read函数读取当前位置之后10个字节的数据并将其存储在buf数组中。然后,我们再次使用lseek函数将文件偏移位置从当前位置再移动10个字节。最后,我们使用write函数将字符串"Hello World"写入文件的当前位置。

关闭文件

当我们完成对文件的操作时,我们需要使用close()函数来关闭文件。close()函数接受一个文件描述符作为参数,然后将该文件描述符从文件表中删除。这样做可以释放文件描述符,以便该文件描述符可用于其他文件。

总结

文件I/O是操作系统中的一个基本组件,它允许我们读取和写入文件。在文件I/O中,我们使用文件描述符来代表打开的文件。文件I/O库提供了一些函数和宏,使我们能够打开、读取、写入和关闭文件。在使用文件I/O时,我们应该始终记住要关闭已打开的文件,并注意错误处理。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值