linux 读写文件接口

linux中,计算机将时间的概念抽象为进程,将空间的概念抽象成文件。


1.文件描述符

linux为每一个打开的文件在内核中建立一个文件表项,该文件表项包括文件的状态信息,存储文件内容的缓冲区,当前文件的读写位置等。一个文件两次被打开的时候会创建两个这样的文件表项。这些文件表项保存在内核中的一个数组里面——文件表。

每个进程在内核中保存有一个整型数组,该数组中每个元素是文件表的下标。因此,使用该数组下标就可以引用打开的文件表项了,该数组下标就是文件描述符。每个进程中文件表下标的数组就是文件描述符数组。所以说,文件描述符是进程与打开文件的一个桥梁。



打开文件:

#include<fcntl.h>

int  open(constchar *pathname, int flags, mode_t mode);

返回值:成功则返回文件描述符,否则返回-1。打开出错有两种:一种是文件名称不存在;第二种是对目录没有写权限。

对于open函数来说,第三个参数仅当创建新文件时(即使用了O_CREAT时)才使用,用于指定文件的访问权限位(accesspermission bits)而且如果此时没有制定,那么将被分配随机的一个值,后来文件访问会出问题。pathname是待打开/创建文件的POSIX路径名(如/home/user/a.cpp);flags用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。

O_RDONLY只读模式

O_WRONLY只写模式

O_RDWR读写模式

打开/创建文件时,至少得使用上述三个常量中的一个。以下常量是选用的:

O_APPEND每次写操作都写入文件的末尾

O_CREAT如果指定文件不存在,则创建这个文件

O_EXCL如果要创建的文件已存在,则返回-1,并且修改errno的值

O_TRUNC如果文件存在,并且以只写/读写方式打开,则清空文件全部内容(即将其长度截短为0)

O_NOCTTY如果路径名指向终端设备,不要把这个设备用作控制终端。

O_NONBLOCK如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O

设置为非阻塞模式

nonblockingmode

以下三个常量同样是选用的,它们用于同步输入输出

O_DSYNC等待物理I/O结束后再write。在不影响读取新写入的数据的

前提下,不等待文件属性更新。

O_RSYNCread等待所有写入同一区域的写操作完成后再进行

O_SYNC等待物理I/O结束后再write,包括更新文件属性的I/O

open返回的文件描述符一定是最小的未被使用的描述符。


关闭文件

#include<unistd.h>

int    close( int fd)

关闭一个文件可以释放所有加在文件上的锁,并且将文件同步到外存。一般情况下,这个函数不会出错;但是在进行网络文件关闭的时候,由于环境特殊,有可能出错,所以要进行出错检查。


创建新文件

#include<fcntl.h>

int    creat(const char * pathname, mode_t mode)


int    open(const char * pathname , O_CREAT | O_WRONLY | O_TRUNC, mode_tmode)



文件定位

#include<unistd.h>

off_tlseek( int filedes , off_t offset, int where)

参数2

1)欲将读写位置移到文件开头时:

lseekintfildes,0,SEEK_SET);

2)欲将读写位置移到文件尾时:

lseekintfildes0,SEEK_END);

3)想要取得目前文件位置时:

lseekintfildes0,SEEK_CUR);

返回值

当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1errno会存放错误代码。

附加说明

Linux系统不允许lseek()对tty装置作用,此项动作会令lseek()返回ESPIPE



文件截断

表头文件#include<unistd.h>

定义函数int    truncate(const char *path, off_t length);

函数说明truncate()会将参数path指定的文件大小改为参数length指定的大小。如果原来的文件大小比参数length大,则超过的部分会被删除

返回值:执行成功则返回0,失败返回-1,错误原因存于errno

错误代码EACCESS参数path所指定的文件无法存取

EROFS欲写入的文件存在于只读文件系统内

EFAULT参数path指针超出可存取空间

EINVAL参数path包含不合法字符

ENAMETOOLONG参数path太长

ENOTDIR参数path路径并非一目录

EISDIR参数path指向一目录

ETXTBUSY参数path所指的文件为共享程序,而且正被执行中

ELOOP参数path有过多符号连接问题

EIOI/O存取错误



读文件

表头文件

#include<unistd.h>

定义函数

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

函数说明

read()会把参数fd所指的文件传送count个字节到buf指针所指的内存中。若参数count0,则read为实际读取到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。

附加说明

如果顺利read()会返回实际读到的字节数,最好能将返回值与参数count作比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取,或者是read()被信号中断了读取动作。当有错误发生时则返回-1,错误代码存入errno中,而文件读写位置则无法预期。

错误代码

EINTR此调用被信号所中断。

EAGAIN当使用不可阻断I/O时(O_NONBLOCK),若无数据可读取则返回此值。

EBADF参数fd非有效的文件描述词,或该文件已关闭。


写文件

表头文件

#include<unistd.h>

定义函数

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

函数说明

write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。当然,文件读写位置也会随之移动。

返回值

如果顺利write()会返回实际写入的字节数。当有错误发生时则返回-1,错误代码存入errno中。

错误代码

EINTR此调用被信号所中断。

EAGAIN当使用不可阻断I/O时(O_NONBLOCK),若无数据可读取则返回此值。

EBADF参数fd非有效的文件描述词,或该文件已关闭。


文件同步

int    fsync(int fd);

fsync函数同步内存中所有已修改的文件数据到储存设备。参数fd是该进程打开来的文件描述符。函数成功执行时,返回0。失败返回-1errno被设为以下的某个值

EBADF: 文件描述词无效

EIO: 读写的过程中发生错误

EROFS,EINVAL:文件所在的文件系统不支持同步

调用 fsync可以保证文件的修改时间也被更新。fsync 系统调用可以使您精确的强制每次写入都被更新到磁盘中。您也可以使用同步(synchronousI/O操作打开一个文件,这将引起所有写数据都立刻被提交到磁盘中。通过在open中指定 O_SYNC标志启用同步I/O

另外,intdatasync (int filedes)只是同步内容,不同步文件属性;intsync()将所有打开的文件进行同步,同步速度快,但并不是真正写到磁盘才返回;而是将改动过的磁盘快内容放在系统队列就返回;所以不一定能保证真正的同步。








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值