非阻塞檔案I/O

來源:互聯網
上載者:User

1.以非阻塞方式開啟檔案

調用open時,使用O_NONBLOCK選項即可。

 

執行個體:

//noblock.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define MAX 100000
#define LEN 1024  /* 使用宏最為緩衝區的大小 */

int main(int argc, char *argv[ ])
{
    int fd1, fd2;
    FILE *fp;
    char buf[MAX]; /* 大檔案的緩衝區 */
    int n, rest;
    char *p = buf;
    char content[LEN];

    if(argc != 3){ /* 缺少檔案名稱 */
        printf("expect args/n");
        exit(1);
    }

    fd1 = open(argv[1], O_RDONLY); /* 輸入檔案 */
    if(fd1 == -1){
        perror("fail to read");
        exit(1);
    }

    fp = fopen(argv[2], "w"); /* 輸出錯誤原因的檔案,使用格式化I/O */
    if(fp == NULL){
        perror("fail to read");
        exit(1);
    }

    fd2 = open("test.txt", O_WRONLY); /* 輸出檔案,低速檔案test.txt檔案 */
    if(fd2 == -1){
        perror("fail to read");
        exit(1);
    }

    rest = read(fd1, buf, MAX); /* 讀檔案的內容到緩衝區 */
    printf("get %d bytes from %s/n", rest, argv[1]);

    while(rest > 0){ /* 當要輸出的內容還有剩餘時繼續輸出 */
        errno = 0;
        n = write(fd2, p, rest); /* 輸出緩衝區內容 */
       
        fprintf(fp, "write %d, errno %s/n", n, strerror(errno)); /* 如果輸出失敗則輸出錯誤原因 */
        if(rest > 0){ /* 計算剩餘的位元組數 */
            p += n;
            rest -= n;
        }
    }

    printf("done/n");

    return 0;
}

 

觀察輸出系統中調用出錯原因的檔案,可以看到很多錯誤號碼為EAGAIN的出錯提示資訊。

 

 

2.將一個開啟的檔案設定為非阻塞方式

 

用fcntl,先用F_GETFL得到狀態標誌字,之後用F_SETFL設定相應的位。

 

//noblock_fcntl.c

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#define MAX 100000
#define LEN 1024

int main(int argc, char *argv[ ])
{
    int fd1, fd2;
    FILE *fp;
    char buf[MAX]; /* 大檔案的緩衝區 */
    int n, rest;
    char *p = buf;
    char content[LEN];
    int flags;

    if(argc != 3){ /* 缺少檔案名稱 */
        printf("expect args/n");
        exit(1);
    }

    fd1 = open(argv[1], O_RDONLY); /* 開啟輸入檔案 */
    if(fd1 == -1){
        perror("fail to read");
        exit(1);
    }

    fd2 = open(argv[2], O_WRONLY); /* 開啟輸出出錯資訊的檔案 */
    if(fd2 == -1){
        perror("fail to read");
        exit(1);
    }

    fp = fdopen(fd2, "w"); /* 開啟檔案,以唯寫的方式 */
    if(fp == NULL){
        perror("fail to open");
        exit(1);
    }

    flags = fcntl(STDOUT_FILENO, F_GETFL, 0); /* 將標準輸出設定為非阻塞形式 */
    if(flags == -1){
        perror("fail to fcntl");
        exit(1);
    }
    flags |= O_NONBLOCK; /* 設定非阻塞標誌 */
    if(fcntl(STDOUT_FILENO, F_SETFL, flags) == -1){ /* 重新設定檔案的狀態標誌 */
        perror("fail to fcntl");
        exit(1);
    }

    rest = read(fd1, buf, MAX); /* 讀入檔案 */
    printf("get %d bytes from %s/n", rest, argv[1]);

    while(rest > 0){ /* 當要輸出的內容還有剩餘時繼續輸出 */
        errno = 0;
        n = write(STDOUT_FILENO, p, rest); /* 輸出緩衝區內容 */
       
        fprintf(fp, "write %d, errno %s/n", n, strerror(errno)); /* 如果輸出失敗則輸出錯誤原因 */
        if(rest > 0){ /* 計算剩餘的位元組數 */
            p += n;
            rest -= n;
        }
    }

    printf("done/n");

    close(fd1); /* 關閉檔案 */

    fclose(fp);

    return 0;
}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.