文件相关系统调用接口open/write/read/close

1.写(write)

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_WRONLY|O_CREAT,0644);//以只写方式打开或不存在的话创建
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    const char* msg = "hello world!\n";
    int count = 5;
    while(count--)//往文件里写5条程序
    {
        write(fd,msg,strlen(msg));
    }
    close(fd);//关闭文件
    return 0;
}

编译通过会产生一个file,运行,打开file会看到5个hello world!

文件相关系统调用接口open/write/read/close_第1张图片
有几个文件描述符默认是被占用的(默认被打开),接下来将write()函数里的第一个参数改为“1”,默认往显示器上写。

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_WRONLY|O_CREAT,0644);//以只写方式打开或不存在的话创建
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    const char* msg = "hello world!\n";
    int count = 5;
    while(count--)//往显示器上写5条程序
    {
        write(1,msg,strlen(msg));
    }
    close(fd);//关闭文件
    return 0;
}

所以程序一旦运行起来,就是往显示器上写。

文件相关系统调用接口open/write/read/close_第2张图片
所以以后再往显示器上写的时候除了printf,又多了一个系统调用接口,write。本质上访问文件是要通过系统调用接口中的文件描述符来访问。

2.读(read)

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_RDONLY,0644);//以只读方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    const char* msg = "hello world\n";
    int size = sizeof(msg);
    char buf[64];
    int count = 5;
    while(count--)//从文件里读
    {
        read(fd,buf,size);//从fd里读,将读到的内容写到buf里
        printf("%s",buf);
    }
    close(fd);//关闭文件
    return 0;
}

以上代码的运行结果会出现一些问题

文件相关系统调用接口open/write/read/close_第3张图片

因为我们在写文件的时候没有把‘\0’写入,但在读的时候不一定会加上
修改代码:

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_RDONLY,0644);//以只读方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    const char* msg = "hello world\n";
    int size = strlen(msg);
    char buf[64];
    while(1)//从文件里读
    {
        size_t s = read(fd,buf,size);//从fd里读,将读到的内容写到buf里
        if(s > 0)//如果s大于零说明读成功了,如果读成功了代表的含义是实际读了多少
        {
            buf[s] = 0;//把最后一个元素设置为零
        }
        else if(s == 0)//如果返回值为0则读到文加结尾
        {
            break;
        }
        printf("%s",buf);
    }
    close(fd);//关闭文件
    return 0;
}

文件相关系统调用接口open/write/read/close_第4张图片

如果把read()函数的第一个参数改为‘0’,代表标准输入,一旦程序运行起来就会停在那里等用户输入。

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_RDONLY,0644);//以只读方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    const char* msg = "hello world\n";
    int size = strlen(msg);
    char buf[64];
    while(1)//从文件里读
    {
        size_t s = read(0,buf,size);//将读到的内容写到buf里
        if(s > 0)//如果s大于零说明读成功了,如果读成功了代表的含义是实际读了多少
        {
            buf[s] = 0;//把最后一个元素设置为零
        }
        else if(s == 0)//如果返回值为0则读到文加结尾
        {
            break;
        }
        printf("%s",buf);
    }
    close(fd);//关闭文件
    return 0;
}

这里写图片描述

文件相关系统调用接口open/write/read/close_第5张图片
最后以ctrl+d结尾。ctrl+d相当于读到文件结尾,读到文件结尾就直接break。
3.现在接口认识完了,那么现在我们来了解一下文件描述符的分配

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_RDONLY,0644);//以只读方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    printf("fd : %d\n",fd);
    return 0;
}

运行结果:
这里写图片描述
也可以多试几个:
首先touch 3个文件:file1 file2 file3

#include
#include
#include
#include
#include

int main()
{
    int fd = open("file",O_RDONLY,0644);//以只读方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    int fd1 = open("file1",O_RDONLY,0644);
    int fd2 = open("file2",O_RDONLY,0644);
    int fd3 = open("file3",O_RDONLY,0644);
    printf("fd : %d\n",fd);
    printf("fd : %d\n",fd1);
    printf("fd : %d\n",fd2);
    printf("fd : %d\n",fd3);
    return 0;
}

文件相关系统调用接口open/write/read/close_第6张图片
说明文件描述符的分配确实是从0开始的小整数
如果还是不能确定那再来一段测试代码:
把‘0’和‘2’关掉(不能关‘1’,若关了就不能显示出来,但有可以管的方法,后续会提到)

#include
#include
#include
#include
#include

int main()
{
    close(0);
    close(2);
    int fd = open("file",O_RDONLY,0644);//以只读方式打开
    if(fd < 0)
    {
        perror("open");
        return 1;//程序失败
    }
    int fd1 = open("file1",O_RDONLY,0644);
    int fd2 = open("file2",O_RDONLY,0644);
    int fd3 = open("file3",O_RDONLY,0644);
    printf("fd : %d\n",fd);
    printf("fd : %d\n",fd1);
    printf("fd : %d\n",fd2);
    printf("fd : %d\n",fd3);
    return 0;
}

文件相关系统调用接口open/write/read/close_第7张图片
因为‘1’没有关所以没有‘1’。

小结:
这里所有的函数必须用到文件描述符,文件描述符默认从‘0’开始分配,而实际上‘0’、‘1’、‘2’已经被占用,分别对应stdin(标准输入)、stdout(标准输出)、stderr(标准错误)。用户分配默认从‘3’开始

你可能感兴趣的:(Linux)