文件相關係統調用接口open/write/read/close

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!

這裏寫圖片描述
有幾個文件描述符默認是被佔用的(默認被打開),接下來將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;
}

所以程序一旦運行起來,就是往顯示器上寫。

這裏寫圖片描述
所以以後再往顯示器上寫的時候除了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;
}

以上代碼的運行結果會出現一些問題

這裏寫圖片描述

因爲我們在寫文件的時候沒有把‘\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;
}

這裏寫圖片描述

如果把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;
}

這裏寫圖片描述

這裏寫圖片描述
最後以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;
}

運行結果:
這裏寫圖片描述
也可以多試幾個:
首先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;
}

這裏寫圖片描述
說明文件描述符的分配確實是從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;
}

這裏寫圖片描述
因爲‘1’沒有關所以沒有‘1’。

小結:
這裏所有的函數必須用到文件描述符,文件描述符默認從‘0’開始分配,而實際上‘0’、‘1’、‘2’已經被佔用,分別對應stdin(標準輸入)、stdout(標準輸出)、stderr(標準錯誤)。用戶分配默認從‘3’開始

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章