linux文件操作函数说明

1:OPEN_MAX常量

1> 文件描述符的范围:0 ~~OPEN_MAX

2> 早期UNIX版本规定OPEN_MAX=19,即一个进程可以打开20个文件

3> 现在UNIX扩展了,一般OPEN_MAX=63,即一个进程可以打开64个文件了

2:open函数

原型 : int open(const char *pathname, into flag, …/*, mode_t mode */) ;

头文件 : #include <sys/types.h>

#include <fcntl.h> // 定义了O_RDWR等常量

#include <sys/stat.h>

作用 : 打开或创建一个文件

参数 :

Oflag

1> 下面三个常量只能选择一个:O_RDONLY, O_WRONLY, O_RDWR

2> 下面的几个常量可以选择一个或者多个进行组合:

1> O_APPEND : 追加

2> O_CREAT : 如果文件不存在时,则创建此文件。使用此选项时,

同时说明第三个参数mode,用其说明该新文件的

存取许可权位

3> O_EXCL : 这个标志可以用来测试文件是否存在,用法:

同时设置O_EXCL和O_CREAT两个标志,如果

文件存在,则调用open函数会出现错误

4> O_TRUNC : 如果此文件存在,而且设置为只读或者只写模式,则

将其长度截短至0

5> O_NONBLOCK: 如果pathname指向的是一个FIFO,一个块设备或者

字符设备文件,则此选项为此文件打开和后续的I/O

操作设置非阻塞方式

6> O_SYNC : 最严格的同并方式,wirte操作在数据和属性都写在

物理磁盘后才返回

3:creat函数

1> 原型 : int creat(const char *pathname, O_RDONLY | O_CREAT | O_TRUNC)

2> 头文件 : #include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

3> 作用 : 新建一个文件,现在可以不用这个函数,直接用open这个函数就可以了

4:creat函数的缺点

1> 只能以写的方式来打开一个文件

2> 在早期时,如果要创建一个临时文件,则应该先creat,然后close,然后再open

3> 现在直接就可以利用这种方式了:

Open (pathname, O_RDONLY | O_CREAT | O_TRUNC, mode_t) ;

5:close函数

1> 原型 : int close

2> 头文件 : <unistd.h>

3> 作用 : 关闭一个文件

6:关于close文件的两个注意点

1> 文件关闭之后,那么在此文件上的所有锁将自动消失

2> 当程序结束后,文件也自动会被关闭,很多程序利用这一特性

7:lseek函数

1> 原型 : off_t lseek(int fd, off_t offset, int whence)

2> 头文件 : #include <sys/types>

#include <unistd.h>

3> 作用 : 动态定位文件指针的位置,使得可以随机访问

4> 参数 :

int whence :

1> SEEK_SET :以文件开头为参照

2> SEKK_CUR :以文件当前指针为参照

3> SEEK_END :以文件末尾为参照

Off_t offset

可以正,也可以复

8:关于lseek的返回值

1> 对于普通文件,如果调用lseek成功,则返回值是非负值

2> 对于一些设备文件,如果调用lseek成功,则返回值可能是负值

―――――――――――――――――――

所以,在测试lseek是否成功被调用时,应该检验它的返回值是不是-1,而不是检验它是不是< 0

9:lseek的延长文件

1> lseek只在内核中记录文件的位置

2> 可以让lseek的结果大于文件的长度,当下次写时,那么就会延长文件,中间的部分用0来填充

10:read函数

1> 原型 : int read(int fd, void *buf, size_t size) ;

2> 头文件 :

#include <unistd.h>

3> 参数 :

Void *buf : 缓冲区

Size_t size : 要求读的字节数目

4> 返回值 :

Ø >0 :实际读到的字节数目

Ø -1 :读时发生错误

Ø 0 :说明达到文件末尾

11:write函数

1> 原型 : int write(int fd, void *bf, size_t size) ;

2> 头文件 :

#include <unistd.h>

3> 参数 :

Void *buf :缓冲区

Size_t size :要求写入的字节数目

4> 返回值 :

Ø >0 :实际写入的字节数目

Ø -1 :表示写操作失败

―――――――――――――――――――

12:一般write操作失败的原因

1> 磁盘已经写满

2> 超过了一个给定进程的文件长度限制

13:BUFSIZE的大小对读写时间的影响

1> 随着bufsize的增大,时间逐渐缩短

2> 当缩短到一定值时,则不会再缩短

14:内核使用三种数据结构来表示文件共享的关系

1> 一个进程对应的各个fd的记录项目

2> 一个fd对应一个文件表

3> 一个文件表还对应一个v结构

15:三种数据结构的组织结构如下所示


1> 每一个进程都对应一个表----进程表项,其中的记录以fd为索引

2> 进程表象中的每一条记录的后部分有一个指针,指向文件表相

3> 文件表相的最后有一个v节点指针,指向V数据结构

―――――――――――――

注意:

1> 内核为所有打开的文件维护一张文件表

2> 文件表的内容:

1> 文件状态标志(读,写,增写,同步,非阻塞)

2> 当前文件位移量

3> V节点指针

3> V节点

1> 包含文件类型

2> 和对此文件操作的函数指针的信息

16:多个文件描述符项指向同一文件表项的情况:

1> 这是允许的

2> 当使用dup函数时,则就会出现不同文件描述符指向相同文件表的情况

3> 父进程和子进程之间也是这种情况

17注意:

当两个进程或者一个进程打开一个文件两次时,则会建立两个文件表项,这样才能保证每个进程都具有

自己的一些属性(例如:读写位置等)

18:两个进程打开同一文件时的图示


1> 文件表项可以有多个

2> V节点只有一个

19:注意

任何一个包含两个或两个以上的函数操作都不可能为原子操作,因为在两个函数中间,内核可能会置换

进程

20:注意

当两个以上的进程同时写同一个文件时,可能会出现问题

前提:两个进程写同一份文件时的数据结构如上图所示

――――――――――――――详细表述―――――――――――――――

进程A和进程B它们的任务相同,都是定位到1500字节处,然后往里面写入东西

1> 进程A打开文件file,并利用lseek定位到1500字节处

2> 进程B打开文件file,并利用lseek定位到1500字节处

3> 内核调度进程B执行,则进程B执行写操作,假设写了100个字节,则V节点里面的信息会更新

到1600字节处

4> 接着,内核调度进程A执行,则进程A执行写操作,但是因为进程A的文件表项里面的文件读写

指针是1500字节,所以这个时候进程A会从1500字节处来写数据

从上面可以看处,已经出现问题了

21: dup函数的两种

1> int dup(int fd)

2> int dup(int fd1, int fd2)

22: int dup(int fd1, int fd2) 说明

1> 参数 :

Fd1 : 已知的

Fd2 : 想申请的fd数值

2> 情况:

1> 如果fd2已经打开,先将其关闭

2> 如果fd2 = fd1,则返回fd2,不关闭它

3> 如果fd2没有打开,则直接复制

23:注意

程序运行时,设置O_SYNC会增加时间

24:fcntl函数的5种功能

1> 复制一个现存的文件描述符

2> 获得/设置文件描述符标记

3> 获得/设置文件状态标志

4> 获得/设置异步I/O有权

5> 获得/设置记录锁



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值