标准io复习

1.标准io和文件io

1.标准io和文件io的区别:

标准io的函数是库函数,不涉及内核层和用户层的上下文切换,效率更高, 库函数不依赖内核的服务,只需要平台提供相应的库,就可以运行库函数,库函数是对内核函数的二次封装,它提供了一个缓存区,每次写数据,先存放到缓存区,当缓存区刷新条件满足时,多个数据同时通过系统调用,从缓存区传到内核空间,避免了频繁访问内核,比系统调用函数效率更高。

文件io的函数是系统调用函数,系统调用函数是内核提供给用户用来调用内核函数服务的,每次都需要通过软中断等指令去调用内核空间中相应的内核函数,涉及频繁地内核和用户之间的上下文切换,调用系统调用函数,会导致出现进程的上下文切换,进程会进入休眠状态,休眠被唤醒会进入就绪队列,排队等待获取时间片,因此效率更低。

可以看做:标准io = 文件io+缓存区

2.标准io缓存区刷新

行缓存刷新:对应stdout,流向终端的标准错误流使用行缓存:1024字节

        遇到回车刷新,缓存区满刷新,程序结束刷新,io关闭刷新,io切换刷新,

        调用fflush(FILE*)手动刷新

全缓存刷新:对应fopen打开的文件使用全缓存:4096字节

        除了遇到回车不刷新外,其他和行缓存刷新一致

无缓存刷新:流向终端的标准错误流使用无缓存:0字节

        errno被赋值int类型的数据,例如赋值2对应错误信息为:No such file or director

2.标准io的函数

1.fopen

FILE *fopen(const char *pathname, const char *mode);

功能:打开文件,通过mode方式打开,通过返回值对文件进行读写操作。

参数:

        参数1:文件路径。

        参数2:打开方式w,w+,r,r+,a,a+,

返回值:成功返回打开文件的指针,失败返回空指针NULL

2.fclose

fclose(FILE *fp)

3.fprintf

int fprintf(FILE *stream, const char *format, ...);

功能:将format写入到stream指向的文件中

int sprintf(char *str, const char *format, ...)

功能:将任意数据类型转为字符串类型

4.fscanf

int fscanf(FILE *stream, const char *format, ...);

功能:将stream指向的文件中的内容读到format指向的变量中

int sscanf(const char *str, const char *format, ...)

功能:将字符串类型转为任意数据类型

5.三个特殊的FILE*文件指针

stdin,stdout,stderr

分别对应scanf,printf,errno

6.feof

int feof(FILE *stream)

功能:判断文件是否读到末尾,读到末尾则返回1,没有读到结尾返回0

7.fgetc,fputc,fgets,fputs

8.fwrite,fread

9.fseek

3.文件io的函数

1.open

int open(const char *pathname, int flags, mode_t mode);

2.read,write

ssize_t write(int fd, const void *buf, size_t count);

ssize_t read(int fd, void *buf, size_t count);

3.文件重定向

int dup2(int oldfd, int newfd);

功能描述:让newfd描述符,重定向到oldfd里面去

举例:dup2(fd,2) 此时调用函数:perror("err"),错误信息就会输出到fd所代表的文件中去

int dup(int oldfd);

功能描述:使用最小未使用的描述符位置处,记录一下oldfd所代表的文件指针,并返回记录处的下标位置

//练习:
    //使用dup和dup2实现以下功能:
    //有这样的2条代码:
        //printf("hello\n");
        //printf("world\n");
        //要求hello输出到文件中,world输出到终端上
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
    int fd;
    fd = open("./myfile", O_RDWR | O_CREAT | O_TRUNC, 0666);
    if(fd < 0)
    {
        perror("open error");
        return -1;
    }
    int sav = dup(1);
    printf("hello\n");
    dup2(fd, 1);
    printf("world\n");
    return 0;
}

4.判断文件权限

int access(const char *pathname, int mode);

功能描述:判断当前程序是否能够以mode形式访问 pathname文件

参数mode:有以下4个选项 F_OK:判断文件是否存在 R_OK:判断文件是否可读 W_OK:判断文件是否可写 X_OK:判断文件是否可执行

返回值:如果能够访问,返回0, 不能访问返回-1

5.获取文件属性

int stat(const char *pathname, struct stat *statbuf);

int fstat(int fd, struct stat *statbuf);

int lstat(const char *pathname, struct stat *statbuf);

上面这三个函数功能相同,都是获取文件属性到struct stat类型的结构体指针中

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    struct stat buf;
    stat("./myfile",&buf);
    if(buf.st_mode | S_IRGRP == buf.st_mode)
    {
        printf("文件可读\n");
    }
}

6.设置掩码umask

什么叫做掩码:其实我们文件创建的时候,真正的文件权限 = 指定的权限 &~ 掩码值

例如:现在 掩码的值是 0111

创建文件的时候,权限是 0777,最终的文件权限值是 0666

创建文件的时候,权限是 0444,最终的文件权限值是 0444

创建文件的时候,权限是 0111,最终的文件权限值是 0000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值