[关闭]
@perkyoung 2015-01-08T17:04:56.000000Z 字数 2590 阅读 1466

UNIX 文件I/O

UNIX


int open(const char* filename, int oflag, .../* mode_t mode */)

  1. fd1 = open(filename, oflags);
  2. fd2 = dup(fd1);
  3. fd3 = open(filename, oflags);

前两行表明fd1,fd2同时指向了同一个文件表项,并且每调用一次open函数都会创建一个新的文件表项,fd则指向了另外一个文件表项,但是这两个文件表项指向同一个v节点


./a.out > outfile 2>&1 与./a.out 2>&1 > outfile的区别

shell是从左向右执行的,第一个首先将标准输出重定向到outfile文件,即文件描述符1代表outfile的文件表项,紧接着2>&1,相当于调用了dup2(1,2)函数,复制了一个文件描述符2,和1同时指向一个文件表项,通过前面可以知晓1指向的是outfile的文件表项,所以最终文件描述符1,2都指向了outfile文件表项。
第二个,首先调用dup(1,2),复制了一个文件描述符2,和1同时指向标准输出的文件表项,紧接着标准输出重定向到outfile文件中,这时候1描述符就指向了outfile文件表项,2依然指向的是标准输出的文件表项


off_t lseek(int fd, off_t offset, int whence);
  1. int main() {
  2. int fd = open("./tmp", O_RDWR | O_CREAT | O_APPEND);
  3. int fd2 = dup(fd);
  4. write(fd, "hello", 5);
  5. int offset = lseek(fd, 0, SEEK_CUR);
  6. char buf[10] = {0};
  7. int offset_2 = lseek(fd2, 0, SEEK_CUR);
  8. read(fd2, buf, 3);
  9. printf("%c\n", buf[0]);
  10. int n = lseek(fd2, -8, SEEK_CUR);
  11. read(fd2, buf, 5);
  12. printf("%s\n", buf);
  13. write(fd, "end!", 4);
  14. return 0;
  15. }

程序中fd,fd2拥有的是同一个文件表项,也就是拥有同一个文件指针,对fd进行写操作会改变文件指针的位置,fd2读数据的时候,用的就是这个更改后的位置:write(fd, "hello", 5);文件指针指向5,read(fd2, buf, 3);会在当前的文件指针5的位置开始读,显然是没有数据的,这时候调用lseek(fd2, -8, SEEK_CUR);,改变了指针位置,read(fd2, buf, 5);,这时候就有数据,下面紧接着write(fd, "end!", 4);,本来是可以在上次读到的位置继续写的,但是O_APPEND这个标志起到了作用,每当write的时候会先将文件标志移动到最后,再写。


ssize_t read(int fd, void *buf, size_t count);

dup,fork新增的文件描述符和原来的文件描述符指向同一个文件表项,
一个文件被多个进程打开,或者被一个进程打开多次,他们是如何协同工作的呢?下面3中数据结果决定了这个性质

int dup(int oldfd);
int dup2(int oldfd, int newfd);

int fcntl(int fd, int cmd, ... /* arg */ );
  1. #define O_ACCMODE 0003
  2. #define O_RDONLY 00
  3. #define O_WRONLY 01
  4. #define O_RDWR 02

判断一个文件的这三个属性,需要用& O_ACCMODE,获得这个标志位

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注