同一个进程内open两次同一文件并读写

来源:互联网 发布:电脑网络显示感叹号 编辑:程序博客网 时间:2024/05/20 18:49

今天和同事讨论一个文件被open两次是否会成功, 以及交叉读写会有什么结果?

 

    FILE* fd1 = NULL; FILE* fd2 = NULL; char buffer1[40];char *buffer2 = "gggggggggg";int ret = 0, ret1;    fd1 = fopen("./text", "rb+");     if(NULL == fd1)     {         perror("open");     } fseek(fd1, 0, 0);ret = fread(buffer1, 1, sizeof(buffer1)-1, fd1);if (ret > 0)buffer1[ret] = '\0';printf("text1: %s \n",  buffer1);        fd2 = fopen("./text", "rb+");     if(NULL == fd2)     {        perror("open");     } fseek(fd2, 0, 0);ret = fread(buffer1, 1, 10, fd2);if (ret > 0)buffer1[ret] = '\0';printf("text2: %s \n",  buffer1);fseek(fd1, 10, 0);ret = fwrite(buffer2, 1, strlen(buffer2), fd1);ret1 = fclose(fd1);printf("fclose(fd1) = %d \n",ret1);fseek(fd2, 15, 0);ret = fread(buffer1, 1, sizeof(buffer1)-1, fd2);if (ret > 0)buffer1[ret] = '\0';printf("text2: %s \n",  buffer1);    return 0; 


 输出的结果是这样的:

text1: aaaaaaaaaaddddddddddcccccccccc
text2: aaaaaaaaaa
fclose(fd1) = 0
text2: dddddcccccccccc

实际上文件内容已经从aaaaaaaaaadddddddddddcccccccccc变为aaaaaaaaaaggggggggggcccccccccc。

 

如果去掉fd2先读取10个字符code

    FILE* fd1 = NULL; FILE* fd2 = NULL; char buffer1[40];char *buffer2 = "eeeeeeeeee";int ret = 0, ret1;    fd1 = fopen("./text", "rb+");     if(NULL == fd1)     {         perror("open");     } fseek(fd1, 0, 0);ret = fread(buffer1, 1, sizeof(buffer1)-1, fd1);if (ret > 0)buffer1[ret] = '\0';printf("text1: %s \n",  buffer1);        fd2 = fopen("./text", "rb+");     if(NULL == fd2)     {        perror("open");     } fseek(fd1, 10, 0);ret = fwrite(buffer2, 1, strlen(buffer2), fd1);ret1 = fclose(fd1);printf("fclose(fd1) = %d \n",ret1);fseek(fd2, 0, 0);ret = fread(buffer1, 1, sizeof(buffer1)-1, fd2);if (ret > 0)buffer1[ret] = '\0';printf("text2: %s \n",  buffer1);    return 0; 

运行结果是这样的。

text1: aaaaaaaaaaggggggggggcccccccccc
fclose(fd1) = 0
text2: aaaaaaaaaaeeeeeeeeeecccccccccc

 

如果去掉//ret1 = fclose(fd1); 则结果如下:

text1: aaaaaaaaaaeeeeeeeeeecccccccccc
text2: aaaaaaaaaaeeeeeeeeeecccccccccc

 

得出如下结论:

如果fd1 write新的数据但不close, 则fd2在fd1 write之前或之后open 并输出文件内容都是原始内容。

如果fd1 write新的数据且close,   如果fd2 在write之前open且没有read数据或之后open, 则close之后read得到的数据是改变后内容。

如果fd2在write&close前就read数据, 则close之后再read数据还是原始的。

write数据并没有实际写入文件,close之后才真正写入。

 fwrite先将数据写入到缓冲区, 如果缓冲区溢出了 才会主动将数据写到文件中, 否则fclose调用之后才会将数据写到文件内。

前面提到fd2在write&close之前就read数据, close再read数据还是原始的, 这是因为fread(100) 读到的可能是1000字节数据而不是100, 当fd1 close之后,

用fd2再读数据实际从缓冲过区读取, 这就是为啥fd1 close之后数据没变的原因。

 

网上找了一些 fread和  read存在差别 , read(100)就只读取100个字节数据, 而fread会多读取数据到缓冲区, 以下程序例子:

 

    FILE* fd1 = NULL; int fd2 = 0; char buffer1[40];char *buffer2 = "6666666666";int ret = 0, ret1;    fd1 = fopen("./text", "rb+");     if(NULL == fd1)     {         perror("open");     } fseek(fd1, 0, 0);ret = fread(buffer1, 1, sizeof(buffer1)-1, fd1);if (ret > 0)buffer1[ret] = '\0';printf("text1: %s \n",  buffer1);     fseek(fd1, 10, 0);ret = fwrite(buffer2, 1, strlen(buffer2), fd1);fd2 = open("./text", O_RDWR); if(0 > fd2) { perror("open"); } lseek(fd2, 0, SEEK_SET);ret = read(fd2, buffer1, 10);if (ret > 0)buffer1[ret] = '\0';printf("text2: %s \n",buffer1);ret1 = fclose(fd1);printf("fclose(fd1) = %d \n",ret1);lseek(fd2, 10, SEEK_SET);ret = read(fd2, buffer1, sizeof(buffer1)-1);if (ret > 0)buffer1[ret] = '\0';printf("text2: %s \n",buffer1);

text1: aaaaaaaaaaffffffffffcccccccccc
text2: aaaaaaaaaa
fclose(fd1) = 0
text2: 6666666666cccccccccc

1 0
原创粉丝点击