欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-07-14 17:35:16
...

1.写(write)

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

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
有几个文件描述符默认是被占用的(默认被打开),接下来将write()函数里的第一个参数改为“1”,默认往显示器上写。

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

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
所以以后再往显示器上写的时候除了printf,又多了一个系统调用接口,write。本质*问文件是要通过系统调用接口中的文件描述符来访问。

2.读(read)

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

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

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

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

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

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

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

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

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

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

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

运行结果:
文件相关系统调用接口open/write/read/close
也可以多试几个:
首先touch 3个文件:file1 file2 file3

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

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
说明文件描述符的分配确实是从0开始的小整数
如果还是不能确定那再来一段测试代码:
把‘0’和‘2’关掉(不能关‘1’,若关了就不能显示出来,但有可以管的方法,后续会提到)

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

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
因为‘1’没有关所以没有‘1’。

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