apue第三章(2)

 

 我的理想是:“让我的家人生活得更好”

6、几个io系统调用

都在 fcntl.h

fcntl.h  sys/types.h                             

open(char * path, oflag, …/*mode_t mode*/)

第一个参数是文件的名字 最长不要超过MAX_NAME

第二个参数是打开文件参数

第三个是创建文件时候提供的umask

第二个参数一般使用:

O_RDONLY 只读的方式打开

O_WRONLY 只写的方式打开

O_RDWR   读写方式打开

O_CREAT 如果文件不存在则创建一个文件,如果文件存在,返回-1

 

 O_EXCL  如果设置了参数O_CREAT ,如果文件不存在,则创建文件的操作为原子操作

O_TRUNC 如果文件存在则把文件长度设置为0

O_SYN    当进行写操作时候,需要完成物理写操作后,再返回

O_NOBLOCK 如果是打开一个fifo文件,一个块特殊文件,一个字符文件,此次操作和后续的io为非阻塞方式。

 

Open的每次打开一个文件返回的都是当前最小的可用的文件描述符

 

fcntl.h  sys/types.h                             

int lseek(int fid, off_t  offset, int where)

返回新的文件位移 出错返回-1

第一个参数是问价描述符

第二个参数是一个 偏移量,第三个参数是参考点

对于第三个参数

SEEK_SET 把偏移到距离文件开头offset

SEEK_CUR 把距离当前的偏移量offset

SEEK_END 偏移量为文件长度+ offset

 

如果文件偏移量大于文件长度,中间会形成一个空洞,空洞会被设置为/0

 

可以使用 pos = lessk(fid, 0 ,SEEK_CUR);来判断一个文件是否支持偏移量

#include<fcntl.h>

#include<stdio.h>

#include<unistd.h>

 

int main()

{

   int pos = -1;

   if((pos = lseek(STDIN_FILENO,0,SEEK_CUR)) == -1)

     printf("can't seek/n");

   else printf("can seek/n");

}

root@white-desktop:/home/junjun/apue/chapter3# ./lseekTest.out  < lseekTest.c

can seek

 

unistd.h:

ssize_t read(int fd, void * buf, size_t nbytes)

read成功 返回读到的字节数,如果达到文件结尾则会返回0 错误返回-1

每读一侧 文件偏移量会想后移动读到的字节数。

 

Unistd.h

ssize_t write(int fd, void * buf, size_t nbytes)

向文件描述符为fd的文件写入nbytes个字节,返回写入的字节数。如果

返回的字节数小于nbytes则出错。在每一次成功写入后,文件偏移量向前移动实际写入的字节数。如果设置了O_APPEND,每次操作之前将文件的偏移量设置为结尾。

 

7、文件的共享,不同程序之间打开同一个文件。

三层结构:

文件描述符表  -- > 文件表项 -- > v节点

1、每一个进程都有一个文件描述符表,每一个表项有对应的文件描述符,和指向文件表的指针。

2、文件表包含了当前的文件偏移,文件状态标志(读写,同步,阻塞等)

和指向v节点的指针。

3V节点(Vvirtual file system 的头个字母),虚拟文件系统是为了一个系统有多个文件系统的情况下使用,v节点中包含了指向i节点的指针,文件的拥有者,文件大小,已经在磁盘的位置信息等都放在v节点中。

 

8 dup

复制文件描述符

int dupint fd

复制文件描述符,返回能够使用的最小的文件描述符。否则返回-1.

例如:

fd1 = dup(fd2);

 fd1fd2指向同一个文件表,也就是有相同的文件状态标示。相同的文件偏移量。fork后父子进程都有相同的文件描述符表,都指向相同的文件表。

 Int dup2(int fd1, int fd2);

返回新的文件描述符,fd2指向fd1指向的文件描述符。如果fd2已经打开则关闭fd2.

 

 9,fcntl

int fcntl(int filde, int cmd, ……);

改变打开文件的性质。

用得比较多的是:取得和修改文件描述符标志:F_SETFD, F_GETFD

 例如

#include<fcntl.h>

#include<unistd.h>

#include<sys/types.h>

#include<stdio.h>

#include<stdlib.h>

int main(int argc , char * argv[])

{

   int val, val1 = 0;

   int fd = open("testfcntl.txt",O_RDONLY|O_APPEND|O_SYNC);

   if((val1 = fcntl(fd,F_GETFL,0)) < 0)

   {

       perror("error");

       return -1;

   }

   printf("fd = %d /n",fd);

   val = val1 & O_ACCMODE;

   if(val == O_RDONLY) printf("rdonly ");

   else if(val == O_WRONLY) printf("wronly " );

   else if(val == O_RDWR) printf("rdwr ");

   else  printf("unknow mode ");

   if(val1 & O_APPEND) printf(",append");

#if defined(O_SYNC)

   if(val1 & O_SYNC) printf(",syn");

#endif

       printf("/n");

close(fd);

}

 

white@white-desktop:/home/junjun/apue/chapter3$ ./a.out

fd = 3

rdonly ,append,syn

           注意 O_REONLY O_REDWR O_WRONLY 是互斥的,必须与O_ACCMODE屏蔽字相与得到读写状态

 

可以使用 fcntl(fd, F_SETFL, val),来设置文件描述符状态。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值