重复打开同一个文件,进行写操作,譬如一个进程中两次调用
open
函数打开同一个文件,分别得到两 个文件描述符 fd1
和 fd2,使用这两个文件描述符对文件进行写入操作,那么它们是分别写(各从各的位置 偏移量开始写)还是接续写(一个写完,另一个接着后面写)?因为这两个文件描述符所对应的读写位置偏移量是相互独立的,所以是分别写。
示例代码:
编译测试:
示例代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
unsigned char buffer1[4], buffer2[4];
int fd1, fd2;
int ret;
int i;
/* 创建新文件 test_file 并打开 */
fd1 = open("./test_file", O_RDWR | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd1)
{
perror("open error");
exit(-1);
}
/* 再次打开 test_file 文件 */
fd2 = open("./test_file", O_RDWR);
if (-1 == fd2)
{
perror("open error");
ret = -1;
goto err1;
}
/* buffer 数据初始化 */
buffer1[0] = 0x11;
buffer1[1] = 0x22;
buffer1[2] = 0x33;
buffer1[3] = 0x44;
buffer2[0] = 0xAA;
buffer2[1] = 0xBB;
buffer2[2] = 0xCC;
buffer2[3] = 0xDD;
/* 循环写入数据 */
for (i = 0; i < 4; i++)
{
ret = write(fd1, buffer1, sizeof(buffer1));
if (-1 == ret)
{
perror("write error");
goto err2;
}
ret = write(fd2, buffer2, sizeof(buffer2));
if (-1 == ret)
{
perror("write error");
goto err2;
}
}
/* 将读写位置偏移量移动到文件头 */
ret = lseek(fd1, 0, SEEK_SET);
if (-1 == ret)
{
perror("lseek error");
goto err2;
}
/* 读取数据 */
for (i = 0; i < 8; i++)
{
ret = read(fd1, buffer1, sizeof(buffer1));
if (-1 == ret)
{
perror("read error");
goto err2;
}
printf("%x%x%x%x", buffer1[0], buffer1[1],
buffer1[2], buffer1[3]);
}
printf("\n");
ret = 0;
err2:
close(fd2);
err1:
/* 关闭文件 */
close(fd1);
exit(ret);
}
示例代码中,重复两次打开
test_file
文件,分别得到两个文件描述符
fd1
、
fd2
;首先通过
fd1
写入 4
个字节数据(0x11、
0x22
、
0x33
、
0x44
)到文件中,接着再通过
fd2
写入
4
个字节数据(0xaa、
0xbb
、 0xcc、
0xdd
)到文件中,循环写入
4
此;最后再将写入的数据读取出来,将其打印到终端。如果它们是分别写,那么读取出来的数据就应该是 aabbccdd……
,因为通过
fd1
写入的数据被
fd2
写入的数据给覆盖了;如果它们是接续写,那么读取出来的数据应该是 11223344aabbccdd……
编译测试:
从打印结果可知,它们确实是分别写。如果想要实现接续写,我们可以使用 O_APPEND 标志来解决这个问题。
当
open
函数使用
O_APPEND
标志,在使用
write
函数进行写入操作时,会自动将偏移量移动到文件末尾,也就是每次写入都是从文件末尾开始。
示例代码:
示例代码:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
unsigned char buffer1[4], buffer2[4];
int fd1, fd2;
int ret;
int i;
/* 创建新文件 test_file 并打开 */
fd1 = open("./test_file", O_RDWR | O_CREAT | O_EXCL | O_APPEND,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (-1 == fd1)
{
perror("open error");
exit(-1);
}
/* 再次打开 test_file 文件 */
fd2 = open("./test_file", O_RDWR | O_APPEND);
if (-1 == fd2)
{
perror("open error");
ret = -1;
goto err1;
}
/* buffer 数据初始化 */
buffer1[0] = 0x11;
buffer1[1] = 0x22;
buffer1[2] = 0x33;
buffer1[3] = 0x44;
buffer2[0] = 0xAA;
buffer2[1] = 0xBB;
buffer2[2] = 0xCC;
buffer2[3] = 0xDD;
/* 循环写入数据 */
for (i = 0; i < 4; i++)
{
ret = write(fd1, buffer1, sizeof(buffer1));
if (-1 == ret)
{
perror("write error");
goto err2;
}
ret = write(fd2, buffer2, sizeof(buffer2));
if (-1 == ret)
{
perror("write error");
goto err2;
}
}
/* 将读写位置偏移量移动到文件头 */
ret = lseek(fd1, 0, SEEK_SET);
if (-1 == ret)
{
perror("lseek error");
goto err2;
}
/* 读取数据 */
for (i = 0; i < 8; i++)
{
ret = read(fd1, buffer1, sizeof(buffer1));
if (-1 == ret)
{
perror("read error");
goto err2;
}
printf("%x%x%x%x", buffer1[0], buffer1[1],
buffer1[2], buffer1[3]);
}
printf("\n");
ret = 0;
err2:
close(fd2);
err1:
/* 关闭文件 */
close(fd1);
exit(ret);
}
在上个示例代码基础上,我们在open函数添加了 O_APPEND 标志,其它部分不变。
编译测试:
从打印出来的数据可知,加入了 O_APPEND 标志后,分别写已经变成了接续写。