阻塞文件

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;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值