Linux操作系统--基础I/O(上)

目录

1.回顾C文件接口

stdin、stdout、stderr

2.系统文件I/O

3.接口介绍

4.open函数返回值

5.文件描述符fd

5.1 0&1&2


1.回顾C文件接口

hello.c写文件

#include<stdio.h>
#include<string.h>

int main()
{
    FILE *fp = fopen("myfile","w");
    if(!fp){
        printf("fopen error!\n");
    }

    const char *msg = "hello friend!\n";
    int count = 5;
    while(count--)
    {
        fwrite(msg,strlen(msg),1,fp);
    }

    fclose(fp);
    
    return 0;
}

hello.c读文件

#include<stdio.h>
#include<string.h>

int main()
{
    FILE *fp = fopen("myfile","r");
    if(!fp){
        printf("fopen error!\n");
    }

    char buf[1024];
    const char *msg = "hello friend!\n";
    while(1)
    {
        //
        size_t s = fread(buf,strlen(msg),1,fp);
        if(s>0){
            buf[s] = 0;
            printf("%s",buf);
        }
        if(feof(fp)){//用于检测文件是否读到末尾
        break;
        }
    }

    fclose(fp);

    return 0;
}

输出信息到显示器

#include<stdio.h>
#include<string.h>

int main()
{
    const char *msg = "hello fwrite\n";
    fwrite(msg,strlen(msg),1,stdout);

    printf("hello printf\n");
    fprintf(stdout,"hello fprintf\n");
    return 0;
}

stdin、stdout、stderr

stdin(0):键盘文件 

stdout(1):显示器文件

stderr(2):显示器文件。(错误信息输出)
进程会默认打开键盘、显示器

三个流的类型都是FILE* ,fopen返回值类型,文件指针

2.系统文件I/O

操作文件,除了上述C接口,我们还可以采用系统接口来进行文件访问。(文件其实是在磁盘上的,磁盘是外部设备,访问磁盘文件其实是访问硬件。几乎所有的库只要是访问硬件设备,必定要封装系统调用,因为之前讲到过,操作系统并不相信用户,不会与用户直接接触,所以提供了接口给用户)

先来直接以代码的形式,实现上面一模一样的代码:

hello.c写文件

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

int main()
{
    umask(0);//修改默认权限掩码
    int fd = open("myfile",O_WRONLY|O_CREAT,0644);
    if(fd<0){
        perror("open");
        return 1;
    }

    int count = 5;
    const char *msg = "hello friend\n";
    int len = strlen(msg);

    while(count--)
    {
        write(fd,msg,len);//fd:后面讲, msg:缓冲区首地址, len:本次读取,期望写入多少个字节的数据, 
        //返回值:实际写了多少字节数据
    }
    
    close(fd);
    return 0;
}

hello.c读文件

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

int main()
{
    int fd = open("myfile",O_RDONLY);
    if(fd<0){
        perror("open");
        return 1;
    }

    const char *msg = "hello friend\n";
    char buf[1024];
    while(1){
        size_t s = read(fd,buf,strlen(msg));
        if(s>0){
            printf("%s",buf);
        }else{
            break;
        }
    }

    close(fd);
    return 0;
}

3.接口介绍

open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

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

pathname:要打开或创建的目标文件

flags:打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。

参数:

        O_RDONLY:只读打开

        O_WRONLY:只写打开

        O_RDWR:读、写打开

                这三个常量,必须指定一个且只能指定一个

        O_CREAT:若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限

        O_APPEND:追加写

返回值:

        成功:新打开的文件描述符

        失败:-1

4.open函数返回值

在认识返回值之前,下来认识两个概念:

  1. 系统调用:系统调用是操作系统提供给用户程序的一种接口,用于让用户程序请求操作系统内核提供的服务。当用户程序需要执行一些特权操作(如文件操作、进程管理等),无法直接访问硬件资源,需要通过系统调用向操作系统内核发出请求。系统调用是通过中断或异常机制实现的,可以看作是用户程序与操作系统内核之间的桥梁。

  2. 库函数:库函数是一组提供特定功能的函数,被封装在软件库中以供程序开发者使用。库函数通常是由编程语言或第三方开发者编写的,用于简化开发过程、提高代码的可重用性和可维护性。库函数可以包含在标准库或第三方库中,程序可以通过链接库函数的方式来调用其中的功能
  • 上面的fopen fclose fread fwrite都是C标准库当中的函数,我们称之为库函数(libc)。
  • 而,open close read write lseek都属于系统提供的接口,称之为系统调用接口

系统调用接口和库函数的关系一目了然

所以,可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发

5.文件描述符fd

文件描述符就是一个整数

5.1 0&1&2

  • Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0,标准输出1,标准错误2.
  • 0,1,2对应的物理设备一般是:键盘,显示器,显示器                        

所以输入输出还可以采用如下方式:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>

int main()
{
    char buf[1024];
    ssize_t s = read(0,buf,sizeof(buf));
    if(s>0)
    {
        buf[s]=0;
        write(1,buf,strlen(buf));
        write(2,buf,strlen(buf));
    }
    return 0;
}

而现在知道,文件描述符就是从0开始的整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files,指向一张表files_struct,该表最重要的部分就是包含一个指针数组,每个元素都是一个指向打开文件的指针。所以,本质上,文件描述符就是数组的下标。所以,只要拿着文件描述符,就可以找到对应的文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值