Linux基础--文件描述符

目录

一.C文件接口

1.hello.c写文件

2.hello.c读文件

3.输出信息到显示器

二、系统文件I/O

0.系统调用和库函数

1.open

2.write

3.read

4.close

三、文件描述符fd

1. 0 & 1 & 2

2.文件描述符分配规则

3.重定向

4.使用dup2系统调用

四、FILE



一.C文件接口

1.hello.c写文件

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


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

    const char * msg = "hello";
    int count = 5;
    while(count--)
    {
        //fwrite(const void * buffer,size_t size, size_t count, FILE * stream) 
        //buffer 数据存储的地址,size 读取的字节大小 count 要读多少个字节 stream 等待被写入的资源
        fwrite(msg,strlen(msg),1,fp);
        //返回值:返回写入元素的个数
    }

    fclose(fp);
    return 0;
}

2.hello.c读文件

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


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

    char buf[1024];
    const char * msg = "hello";
    while(1)
    {
        //size_t fread(void * buffer, size_t size, size_t count, FILE * stream)
        //将stream中的文件读取count个size字节到buffer中
        ssize_t s = fread(buf,1,strlen(msg),fp);
        if(s > 0)
        {
            buf[s] = 0;
            prinf("%s",buf);
        }

        if(feof(fp))
            break;

    }

    fclose(fp);
    return 0;
}

3.输出信息到显示器

int fprintf(FILE * stream, cosnt char * format, ...)
stream是文件指针,表示要输出到的文件
format是格式化字符串
返回值是成功输出的字符个数

二、系统文件I/O

0.系统调用和库函数

fopen,close,fread,fwrite都是C库中的函数,称为库函数(libc)

open,close,read,write,lseek都是系统提供的接口,称为系统调用接口

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

1.open

返回值:返回值类型为int ,大于0,表示成功打开,这个数字称为文件描述符

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

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

pathname:要打开或者要创建的目标文件
flags:
        O_RDONLY:只读打开
        O_WRONLY: 只写打开
        O_RDWR : 读,写打开
        这三个常量,必须指定一个且只能指定一个
        O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
        O_APPEND: 追加写
mode:文件被新创建,指定权限为mode

2.write

#include<unistd>
//将buf中的nbyte个字节写到fd对应的文件中
ssize_t write(fd,const void * buf,size_t nbyte);
//写入成功返回写入文档的bytes,失败返回-1

3.read

#include<unistd.h>
//读取fd对应文件中的count个字符,放到buf缓冲区中
ssize_t read(int fd, void * buf, size_t count);
//成功返回读取的字节数
//返回0 表示已经读到了文件末尾
//失败返回-1,并设置errno

4.close

#include<unistd.h>
int close(int fd);
//成功返回0,出错返回errno

当一个进程终止时,内核对该进程所有尚未关闭的文件描述符,调用close关闭,所以即使用户程序不调用close,在终止时内核也会自动关闭它打开的所有文件。但是对于一个长年累月运行的程序(比如网络服务器),打开的文件描述符一定要记得关闭,否则随着打开的文件越来越多,会占用大量文件描述符和系统资源

三、文件描述符fd

通过open函数,文件描述符就是一个整数

1. 0 & 1 & 2

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

文件描述符就是从0开始的整数。进程要读取文件,首先os创建进程pcb,从磁盘向内存中加载文件,这个过程创建struct_file,里面包含文件的各种属性。pcb中有一张表,存放文件描述符,表中存放struct_file指针,通过表中数组下标索引找到对应文件指针,进而访问文件。所以,本质上文件描述符就是该数据的下标,所以拿到了fd,就可以找到对应的文件。

2.文件描述符分配规则

在file_struct 数组中,找到当前没有被使用的最小的一个下标,作为新的文件描述符

3.重定向

我们之前使用 > >> < 等符号,将数据重定向指定文件中。

重定向的本质就是:比如我们要往显示器上打印文件,应该对应1号fd,现在修改打印到myfile中,myfile是三号文件,即修改fd就可以重定向

4.使用dup2系统调用

#include<unistd.h>
int dup2(int oldfd, int newfd);

oldfd指向a.txt,newfd指向b.txt,调用成功后,newfd和b.txt关闭,newfd指向a.txt(oldfd被保留)

四、FILE

IO相关函数与系统接口对应,并且库函数封装系统调用,本质上任何文件都是通过访问fd来访问的

C库中的FILE结构体内部必定封装了fd


猜你喜欢

转载自blog.csdn.net/jolly0514/article/details/132570645