天天看點

Linux fopen/freopen/fdopen 函數

文章目錄

      • 一、函數聲明
      • 二、執行個體
        • 2.1 fopen
        • 2.2 fopen運作結果
        • 2.3 fdopen
        • 2.4 運作結果
        • 2.5 fclose會關閉檔案句柄?
        • 2.6 運作結果

一、函數聲明

#include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);
// 從檔案描述符建立并關聯一個FILE.
FILE *fdopen(int fd, const char *mode);
// freopen,重新打開檔案,并清除原來的定向(位元組流定向,寬位元組流定向)
FILE *freopen(const char *pathname, const char *mode, FILE *stream);
           
fdopen,該函數與fopen的差別在于,

fdopen可以支援任何類型的檔案的描述符

但是fopen支援的相對少一些,fopen不支援管道,socket的檔案直接打開。

二、執行個體

2.1 fopen

// fopen版本
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char **args)
{
    FILE *pf;
    char buf[4096] = {0};
    
    pf = fopen("hotice0", "r");
    if (!pf) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    fscanf(pf, "%s", buf);

    printf("%s\n", buf);

    fclose(pf);
    return EXIT_SUCCESS;
}
           

2.2 fopen運作結果

[email protected]:~/Documents/Unix_Program$ cat hotice0 
[email protected]:~/Documents/Unix_Program$ ./fopen 
test
           

2.3 fdopen

#ifndef __USE_POSIX
#define __USE_POSIX
#endif

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

int main(int argc, char **args)
{
    FILE *pf;
    int fd;
    char buf[4096] = {0};
    
    fd = open("hotice0", O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    pf = fdopen(fd, "r");
    // pf = fopen("hotice0", "r");
    if (!pf) {
        perror("fopen");
        close(fd);
        exit(EXIT_FAILURE);
    }

    fscanf(pf, "%s", buf);

    printf("%s\n", buf);

    fclose(pf);
    return EXIT_SUCCESS;
}
           

2.4 運作結果

與上面fopen結果一緻
[email protected]:~/Documents/Unix_Program$ cat hotice0 
[email protected]:~/Documents/Unix_Program$ ./fopen 
test
           

2.5 fclose會關閉檔案句柄?

我們在fclose之後,調用read進行讀取看看
#ifndef __USE_POSIX
#define __USE_POSIX
#endif

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

int main(int argc, char **args)
{
    FILE *pf;
    int fd;
    char buf[4096] = {0};
    
    fd = open("hotice0", O_RDONLY);
    if (fd < 0) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    pf = fdopen(fd, "r");
    // pf = fopen("hotice0", "r");
    if (!pf) {
        perror("fopen");
        close(fd);
        exit(EXIT_FAILURE);
    }

    fscanf(pf, "%s", buf);

    printf("%s\n", buf);

    fclose(pf);

    if (read(fd, buf, 4096) < 0) {
        perror("read");
        exit(EXIT_FAILURE);
    }
    return EXIT_SUCCESS;
}
           

2.6 運作結果

test
read: Bad file descriptor
           
可以看到fclose不僅釋放了緩存(即标準IO相關),還關閉了檔案描述符。

繼續閱讀