Linux下的基础IO操作

首先我们先来回顾一下C语言下文件接口

一.打开文件
这里写图片描述
1.先说一下fopen函数,它的第一个参数path是一个通过路径指向的字符串,即文件名,第二个参数mode是采用什么方式打开该文件,具体mode的值如下
这里写图片描述
r以只读方式打开
r+方式打开可以提供读写操作
w方式只要打开一个文件,如果文件里有内容,那么将清除内容,可以理解为只写操作
w+方式打开与r+方式一样提供读写,但如果文件不存在则会创建该文件,
a以附加的方式打开,能够在文件末尾写入,如果文件不存在则会创建该文件,如果文件内有内容,想继续写内容不删除原来的内容,则a的方式可以做到
a+以读和附加的方式打开,能够在文件末尾写入,如果文件不存在则会创建该文件,最初读文件的位置在文件开头,但是写入的时候总是在文件结尾。

通常的来说,r方式和w方式用的最多,因为通常我们打开文件只要求完成一个功能。

2.对于fdopen函数,它将流与现有的文件描述符fd相关联,它的第一个参数是一个文件描述符,第二个参数流的模式(之前介绍的6种流)必须与文件描述符的模式兼容。

3.对于freopen函数,前两个参数与fopen相同,它的作用打开一个文件,并将其与流指向的流关联起来它,它的主要用途是更改与标准文本(stdout,stdin,stderr)相关联的文件。

这三个函数成功的返回值都是一个FILE* 文件指针,否则将返回NULL并将errno设置为显示错误。

二.读文件与写文件
这里写图片描述
fread和fwite函数用于读写记录,参数ptr表示用于接收数据的位置,size表示要读或写的每个记录的字节数,nmemb表示要读取nmemb个大小为size个字节的记录,这些记录在ptr中连续存放,共占用(size * nmemb)个字节,fread从文件stream中读出(size * nmemb)个字节保存到ptr中,而fwrite把ptr中的(size * nmemb)个字节写到文件stream中。

它们的返回值返回读或写的记录数,成功时返回的记录数等于nmemb,出错或到达文件末尾时返回的记录数小于nmemb,也可能返回0。
fread函数不区分文件结束和错误,我们需要调用ferror和feof来确定发生了什么。

feof函数测试流指向的流的文件尾指示符,如果设置为非零,则返回非零。
ferror函数测试流指向的流的错误指示器,如果设置为非零,则返回非零。

关于这两个函数的测试代码如下
fwrite
这里写图片描述
执行结果如下
这里写图片描述

fread
这里写图片描述
执行结果如下,这里的myfile文件是已经执行过了fwrite后已经写入了内容
这里写图片描述

三.关闭文件
这里写图片描述
关闭文件很简单,在上面的代码中也有用到,只要传一个文件指针就能够实现。
成功将返回0,否则将返回EOF,并设置error来表示错误。

另外需要说明的是,C打开文件时默认打开的三个流stdin,stdout和stderr ,这三个的类型都是FILE*,都是fopen的返回值类型,它们都是文件指针。

/*********************************************************************************************/
接下来我们看一下系统级别的I/O,也就是操作系统提供给用户的一些系统调用。同样地,我们也是从按打开文件,读写文件,关闭文件来说明。

一.打开文件
这里写图片描述

open函数有两种传参形式,这个我们稍后再说,我们先来看一下它的返回值。open函数如果调用成功返回的是一个最低编号的文件描述符,它是一个非负数,前面说过打开一个文件的时候系统会默认打开三个文件stdin,stdout,stderr,它们的对应的文件描述符分别是0,1,2,所以一般来说,在不先关闭以上三个文件的前提下,系统打开的文件对应的文件描述符应是3;如果调用不成功,则返回-1。

第一个参数是打开文件的路径名,也就是文件名。
对于第二个参数,首先它必须包含以下三个参数之一:O_RDONLY(只读), O_WRONLY(只写), or O_RDWR(可读可写),这是打开文件的方式。

此外更多的文件状态标志和文件创建标志如下:

  • O_APPEND
    文件在append模式中打开。在每次写入之前,文件偏移位置位于文件的末尾。如果多个进程同时向文件追加数据,那么O_APPEND可能会导致NFS文件系统上的文件损坏。这是因为NFS不支持对文件的附加,因此客户机内核必须模拟它,这是不可避免的竞态条件。
  • O_ASYNC
    启用信号驱动的I / O:在这个文件描述符上能输入和输出时生成一个信号(默认为SIGIO,可以通过fcntl进行更改)。该特性只适用于终端、伪终端、套接字、管道和FIFOs(匿名管道)。
  • O_CLOEXEC
    启用新文件描述符的close-on-exec标志。指定此标志允许程序避免额外的fcntl F_SETFD操作来设置FD_CLOEXEC标志。此外,在一些多线程程序中使用此标志是必要的,因为使用一个单独的fcntl F_SETFD操作来设置FD_CLOEXEC标志,这并不足以避免竞态条件一个线程在另一个线程执行fork和execve的同时打开一个文件描述符。
  • O_CREAT
    如果文件不存在,它将被创建。第三个参数mode指定在创建新文件时使用的权限。当指定O_CREAT时,必须提供这个参数;如果没有指定O_CREAT,则忽略第三个参数mode。mode的值一般用8进制的数来表示,如0666表示拥有者,所属组和其他用户对该文件的权限都是可读可写,这与权限的设置方式一样。
  • O_DIRECT
    尝试将I / O的缓存效果最小化到此文件。总的来说,这将降低性能,特殊情况下它是有用的,例如应用程序自己进行缓存时。文件I / O直接由用户空间缓冲区完成。I/ O是同步的,即在完成读或写时,保证数据被传输。
  • O_DIRECTORY
    如果路径名不是目录,则导致打开失败
  • O_EXCL
    确保此调用创建文件:如果此标志与O_CREAT一起指定,且路径名已经存在,那么open()将会失败。如果没有指定O_CREAT,则O_EXCL的行为是未定义的。
  • O_NOATIME
    当读取文件时,不要更新文件的最后访问时间(inode中的st_atime)
  • O_NOCTTY
    如果路径名是指终端设备,即使是进程不存在,它也不会成为进程的控制终端。
  • O_NOFOLLOW
    如果路径名是一个符号链接,则打开失败。
  • O_NONBLOCK或O_NDELAY
    当可能时,文件以非阻塞模式打开。
  • O_TRUNC
    如果文件已经存在,并且是一个常规文件,而开放模式允许写入(即:,是O_RDWR或O_WRONLY),文件将被截断为长度0。如果文件是FIFO或终端设备文件,则忽略O_TRUNC标志。

二.读写文件
这里写图片描述
read函数的作用是从文件描述符为fd的文件中,读取count个字节的数,读到buf当中;
write函数的作用是将buf中count个字节的数写到文件描述符为fd的文件当中。

对于返回值,我们可以注意到,两个函数返回的都是ssize_t,这个类型其实是signed size_t;size_t是无符号的数据类型,二ssize_t是有符号的数据类型,也就是说它可以表示负数。

read函数调用成功时,它将返回读取的字节数。它的返回值是可能小于count的值的,主要的原因可能是我们EOF关闭了文件,或者是我们从管道或是终端在读取数据,也可能read被一个信号终止了。如果count传的是0,则read不起作用并返回0;如果函数最后返回0,表示已到达文件尾或无可读取的数据;如果调用失败,则返回的是-1。

write函数调用成功时,返回写入的字节数。否则返回-1。

read和write的测试函数如下:
write

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

int main()
{
    umask(0);
    int fd = open("myfile",O_WRONLY|O_CREAT,0666);
    if(fd < 0)
    {
        perror("open\n");
        return 1;
    }

    const char* buf="hello world\n";
    int count=5;
    while(count--)
    {
        ssize_t s=write(fd,buf,strlen(buf));
        if(s<0)
        {
            perror("write\n");
        }
    }
    return 0;
}

这里写图片描述

read

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

int main()
{
    int fd=open("myfile",O_RDONLY);
    if(fd<0)
    {
        perror("open!\n");
        return 1;
    }

    char buf[1024];
    const char* msg="hello world\n";

    while(1)
    {
        ssize_t s=read(fd,buf,strlen(msg));
        if(s>0)
        {
            printf("%s",buf);
        }
        else
        {
            break;
        }
    }

    close(fd);
    return 0;
}

这里写图片描述

三.关闭文件
这里写图片描述
这个很简单,成功返回0,失败返回-1。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值