第七章 文件与I/O(4)

文件共享

打开文件内核数据结构

一个进程两次打开同一个文件

一个进程能打开1024个文件描述符,没打开一个文件,内核会生成一个文件表,文件表中的v节点指针指向v节点表,v节点部分信息就是stat函数返回的信息,i节点信息,当我们打开一个文件的时候,会将文件系统中i节点信息拷贝到v节点信息对应的i节点信息中(i节点号,文件存在那一块中,)

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <pwd.h>
#include <time.h>

#define ERR_EXIT(m) \
        do  \
        {   \
            perror(m); \
            exit(EXIT_FAILURE); \
        }while(0)

int main(int argc, char* argv[])
{
    int fd1,fd2;
    char readbuf1[1024] = {0};
    char readbuf2[1024] = {0};

    //open会打开文件表,文件表会记录当前文件的状态标志,当前文件的偏移量,引用计数,v节点指针,
    //每个fd都是独立的,所以偏移量这些也是唯一的,不会影响其他fd的偏移量
    fd1 = open("test.txt",O_RDONLY);
    if(fd1 == -1)
        ERR_EXIT("open");
    read(fd1, readbuf1, 4);
    printf("readbuf1 = %s\n",readbuf1);
    
    //open会新开文件表
    fd2 = open("test.txt",O_RDWR);
    if(fd2 == -1)
        ERR_EXIT("open");
    read(fd2, readbuf2, 4);
    printf("readbuf2 = %s\n",readbuf2);
    //写入数据后,v节点中的i节点对应硬盘中的数据改变了
    write(fd2,"AAAAA",6);


    memset(readbuf1, 0, sizeof(readbuf1));
    read(fd1, readbuf1, 6);
    printf("readbuf1 = %s\n",readbuf1);


    close(fd1);
    close(fd2);

    return 0;
}

两个进程打开同一个文件

复制文件描述符(dup、dup2、fcntl)

dup

功能:
创建一份oldfd的拷贝,使用最小的可用的文件描述符作为新的文件描述符。

int dup(int oldfd);
参数:
    oldfd : 文件描述符
返回值:
   成功:返回新的文件描述符
   出错:返回-1.注意:由dup函数返回的新文件描述符一定是当前可用文件描述符中的最小值。

输出重定向

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <pwd.h>
#include <time.h>

#define ERR_EXIT(m) \
        do  \
        {   \
            perror(m); \
            exit(EXIT_FAILURE); \
        }while(0)

int main(int argc, char* argv[])
{
    int fd1;
    fd1 = open("test2.txt", O_WRONLY);
    if(fd1 == -1)
        ERR_EXIT("open");

    close(1);
    dup(fd1);
    printf("hello\n");

    //等同于上面的代码
    //dup2(fd1,1);

    close(fd1);

    return 0;
}

dup2

功能:
dup2用来复制参数oldfd所指的文件描述符,并将oldfd拷贝到参数newfd后一起返回。强制使用新的文件描述来复制,不管原来的文件描述符是否空闲

  • 若参数newfd为一个打开的文件描述符,则newfd所指的文件会先被关闭,
  • 若newfd等于oldfd,则返回newfd,而不关闭newfd所指的文件。
  • dup2所复制的文件描述符与原来的文件描述符共享各种文件状态。共享所有的锁定,读写位置和各项权限或flags等等.
int dup2(int oldfd, int newfd);
参数:
    oldfd : 文件描述符
    newfd : 文件描述符
返回值:
    成功: 返回新的文件描述符
    出错: 返回-1. 注意:由dup2函数返回的新文件描述符一定是当前可用文件描述符中的最小值。

 
newfd和oldfd具有的共同点:
(1)相同的打开文件(管道)。
(2)相同的文件指针,即两个文件共享一个文件指针。
(3)相同的访问模式。读取、写入。
(4)相同的文件状态标识。

猜你喜欢

转载自www.cnblogs.com/s3320/p/11329390.html