系统编程-系统调用io/文件io

文件描述符fd

文件描述符优先使用当前数组标记中小的去使用
在这里插入图片描述

在文件io中贯穿始终的类型
文件操作:

  • open(const char* pathname, int flags); // 成功返回文件描述符,失败-1
    cache是读的加速机制,buf是写的加速机制
    man 2 open
    该函数使用变参函数实现的,重载是定参实现,可变参数是变参实现的
作用
o_rdonly只读r
o_edwr读写r+
o_wronly只写w
o_trunc截断,清空w
o_create创建文件描述w
o_nonblock非阻塞能做就做,不能做就再等等
o_sync同步
  • close(fd);
  • read(int fd, void * buf, size_t count); 从文件描述符中读到buf中count个字节,返回读到多少个,失败返回-1,errno记录错误
  • write(int fd, const void * buf, size_t count); 从buf写到fd中count个
  • lseek(int fd, off_t offset, int whence); 对文件描述符定位
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
    if (argc < 3)
    {
        fprintf(stderr, "usage");
        exit(1);
    }
    int srcfd;
    int dstfd;

    srcfd = open(argv[1], O_RDONLY);
    if (srcfd < 0)
    {
        perror("open");
        exit(1);
    }
    
    dstfd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0600);
    if (dstfd < 0)
    {
        close(srcfd);
        perror("open");
        exit(1);
    }
#define SIZE 1024
    char buf[SIZE];
    int len;
    int ret;
    int pos = 0;
    while (1)
    {
        len = read(srcfd, buf, SIZE);
        if (len < 0)
        {
            // 读取出错
            perror("read");
            break;
        }
        else if (len == 0)
        {
            break;
        }
        while (len > 0)
        {
        // 信号可以打断系统调用,
            ret = write(dstfd, buf + pos, len);
            if (ret < 0)
            {
                perror("write()");
                exit(1);
            }
            pos += ret;
            len -= ret;
        }
    }

    close(srcfd);
    close(dstfd);
    return 0;
}

将文件io与标准io区别
系统、文件io是调用一次,执行一次,马上进入内核操作,没有缓冲模式,—响应速度快
标准io是有缓冲区的----吞吐量大
一般情况下吞吐量—标准io更好
标准io和文件io不可混用

int fileno(FILE*); // 将FILE转换为文件描述符fd
FILE* fdopen(int fd, const int mode); 将文件描述符转成FILE*
strace 命令可以跟踪一个可执行文件的系统调用
time 命令可以测试一个可执行文件的运行时间

io的效率问题:

文件共享:
删除一个文件的第10行
lseek 11 + read + lseek + write
truncate(const char * path, off_t length); // 系统调用:未打开文件截断到长度
ftruncate(int fd, off_t length); // 将已经打开的文件截断到长度

原子操作:不可分割的操作,解决竞争和冲突

程序中的重定向:dup dup2
使用当前文件最小的文件描述符作为新的文件描述符,将原fd拷贝到新fd位置上
dup操作不是原子操作,将先关闭后赋值fd分开操作,会导致多进程编程出错

dup2(oldfd, newfd); // 是个原子操作
// 如果new和old相同,则dup2什么都不做

同步:sync fsync fdatasync
sync 同步缓冲区
fcntl(int fd , int cmd , …); 对文件描述符做cmd操作
ioctl(); 设备相关的内容

dup(fd)等效于fcntl(fd, F_DUPFD, 0);
dup2(fd, fd2)等效于 close();fcntl(fd,F_DUPFD, fd2);

/dev/fd/目录: 虚目录,显示当前文件描述符的信息
命令 ll /dev/fd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值