2016-12-10 142 views
4

所以我必须解决这个锻炼情况不同。编写一个程序,最多需要三个命令行参数:写()在两种情况下

$ atomic_append filename num-bytes [x] 

这个文件应该打开指定的文件名(如果有必要创建它),并通过使用write()一次写一个字节追加num-bytes字节的文件。默认情况下,程序应使用O_APPEND标志打开文件,但如果提供了第三个命令行参数(x),则应该省略O_APPEND标志,而应在每个write()之前执行lseek(fd, 0, SEEK_END)调用。在同一时间运行该程序的两个实例,而不x参数写入1个百万字节到同一个文件:

$ atomic_append f1 1000000 & atomic_append f1 1000000 

重复相同的步骤,写入不同的文件,但是这次指定x参数:

$ atomic_append f2 1000000 x & atomic_append f2 1000000 x 

使用ls –l列出文件f1和f2的大小并解释差异。

所以这是我写的:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 

int main(int argc, char *argv[]) { 
     int fd, flags, num_bytes; 
     if (argc < 3 || strcmp(argv[1], "--help") == 0) { 
       printf("Usage: %s filename num-bytes [x]\n", argv[0]); 
       return 1; 
     } 
     num_bytes = atoi(argv[2]); 
     if (argc == 4 && strcmp(argv[3], "x") == 0) { 
       fd = open(argv[1], O_CREAT | O_WRONLY, 0666); 
       if (fd == -1) 
         perror("open"); 
       while (num_bytes-- > 0) { 
         lseek(fd, 0, SEEK_END); 
         write(fd, "a", 1); 
       } 
       if (close(fd) == -1) 
         perror("close"); 
     } 
     else { 
       fd = open(argv[1], O_CREAT | O_APPEND | O_WRONLY, 0666); 
       if (fd == -1) 
         perror("open"); 
       while(num_bytes-- > 0) 
         write(fd, "a", 1); 
       if (close(fd) == -1) 
         perror("close"); 
     } 
     return 0; 
} 

现在后我跑了它的要求:

[email protected]:~/System/5$ ./a.out f1 1000000 & ./a.out f1 1000000 
[1] 4335 
[1]+ Done     ./a.out f1 1000000 
[email protected]:~/System/5$ ./a.out f2 1000000 x & ./a.out f2 1000000 x 
[1] 4352 
[1]+ Done     ./a.out f2 1000000 x 
[email protected]:~/System/5$ ls f1 f2 
f1 f2 
[email protected]:~/System/5$ ls -l f* 
-rw-rw-r-- 1 abhinav abhinav 2000000 Dec 10 16:23 f1 
-rw-rw-r-- 1 abhinav abhinav 1000593 Dec 10 16:24 f2 

肯定地说,有文件大小的差异我有些无法清楚地了解为什么?我搜索,发现某处这样的解释:

尺寸有绝对不同:

-rw------- 1 posborne posborne 1272426 2012-01-15 21:31 test2.txt 
-rw------- 1 posborne posborne 2000000 2012-01-15 21:29 test.txt 

哪里的test2.txt未经O_APPEND运行。 test2.txt由 短于 文件末尾的 末尾没有发生与写入同时发生(相当于 频繁)的次数(或字节由于次数)。

但它似乎没有任何意义。那么为什么尺寸的差异呢?

回答

1

此代码,在不与O_APPEND打开的文件运行:

  while (num_bytes-- > 0) { 
        lseek(fd, 0, SEEK_END); 
        write(fd, "a", 1); 

写入文件的结束的位置,因为它是当调用lseek()作出。该文件的结尾可以在lseek()write()调用之间的时间内更改。

此代码,对用O_APPEND打开的文件:

  while(num_bytes-- > 0) 
        write(fd, "a", 1); 

保证通过write()荷兰国际集团与O_APPEND打开的文件的标准行为”写入到文件的端不管哪一端是

这就是O_APPEND标志的整个点 - lseek()然后write()不起作用

+0

在'write()'之前,在lseek()'的帮助下,文件末尾如何在两次调用之间改变?他们不是原子吗? –

+1

'lseek()'是一个电话。 'write()'是另一个。序列'lseek(); write();'是两个独立的调用 - 两个不能自动工作。并且文件的结尾可以在这两个调用之间改变。再次 - 这是为什么存在'O_APPEND'标志。 –