系统之家 - 系统光盘下载网站!

当前位置:系统之家 > 系统教程 > Linux中文件I/O操作

Linux下文件I/O操作的相关知识(3)

时间:2014-12-26 15:58:35 作者:qipeng 来源:系统之家 1. 扫描二维码随时看资讯 2. 请使用手机浏览器访问: https://m.xitongzhijia.net/xtjc/20141226/33535.html 手机查看 评论

  现在对前一节文件I/O(1)的几个操作进一步说明:

  1. 完成write之后,文件中当前偏移量即所增加的字节数。如果当前偏移量大于文件长度,则将i节点中当前文件长度设为当前文件偏移量。

  2. 用O_APPEND打开一个文件,相应标志会被设置到文件状态标识中。每次写时,当前偏移量会被设置为i节点中的文件长度

  3. lseek定位到文件尾端时,则文件当前偏移量会被设置为当前文件长度。

  可能有多个文件描述符指向同一文件表项。调用dup和fork时都能看到这一点。

  多个进程读同一文件能正确工作。但多个进程写同一文件时,可能产生预期不到的后果。可以利用原子操纵避免这种情况。

  原子操作

  一般而言,原子操作指的是由多部组成的操作。如果该院自地执行,要么执行完所以步骤,要么一步也不执行。

  1. 添加至一个文件

  考虑一个进程,它要讲数据添加到一个文件尾端。早期UNIX不支持open,所以可以如下实现:

  代码如下:

  if(lseek(fd, 0L, 2)《0)

  err_sys(“lseekerror”);

  if(write(fd, buf, 100) != 100)

  err_sys(“writeerror”);

  对于单个进程,这段程序能正常工作。但多个进程就不一定。结社进程A和B都对同一文件进行添加操作。每个进程都打开该文件,此时数据结构之间关系如图2中所示。假定A调用lseek,将A的当前偏移量设置为1500。进程B执行lseek也将其当前偏移量设为1500。然后B调用write,将当前偏移量增至1600。然后内核又进行进程切换使进程A恢复运行,当A调用write时,从其当前偏移量1500处将数据写入,将替换B刚写入到该文件中的数据。

  问题出在逻辑操作“定位到文件尾端处,然后写“使用了两个分开的函数调用。解决办法是使这两个操作成为一个原子操作。O_APPEND标识,使内核每次对文件进行写之前,都将进程当前偏移量设置到该文件的尾端处。

  2.pread和pwrite函数

  原子性地定位搜索和执行I/0。

  代码如下:

  #include 《unistd.h》

  ssize_t pread(int fd, void *buf, size_tcount, off_t offset);

  ssize_t pwrite(int fd, const void *buf,size_t count, off_t offset);

  ssize_t pread(int fd, void *buf, size_tcount, off_t offset);

  ssize_t pwrite(int fd, const void *buf,size_t count, off_t offset);

  dup和dup2函数

  代码如下:

  #include 《unistd.h》

  int dup(int oldfd);

  int dup2(int oldfd, int newfd);

  上面两个函数都可用来复制一个现存的文件描述符。

  由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用newfd参数指定新描述符的数值。如果newfd已经打开,则先将其关闭。如果newfd等于oldfd,则dup2返回newfd而不关闭它。

  假定我们的进程执行了:

  newfd = dup(1);

  当此函数执行时,假设下一个可用的描述符是3。因为这两个描述符指向同一个文件表项,所以他们共享文件标志以及同一文件偏移量。

  sync、fsync和fdatasync

  代码如下:

  #include 《unistd.h》

  void sync(void);

  int fsync(int fd);

  int fdatasync(int fd);

  当将数据写入文件时,内核通常将数据复制到一个缓冲区,直到缓冲区写满,再将缓冲区排路输出队列,然后等待其到达队首,才进行实际的I/O操作。这种输出防暑被称为延迟写。延迟写减少了磁盘的读写次数,但却降低了文件内容的跟新速度。当系统发生故障时,延迟写可能造成文件跟新内容的丢失。为了保证磁盘上实际文件系统与缓冲区高速缓存中内容一致性,UNIX系统提供了sync、fsync和fdatasync 三个函数。

  fcntl函数

  代码如下:

  #include 《unistd.h》

  #include 《fcntl.h》

  int fcntl(int fd, int cmd, 。。。 /* arg */ );

  可以改变已经打开文件的性质。

  复制一个现有的描述符(cmd=F_DUPFD)

  获得或设置文件描述符(cmd=F_GETFD|F_SETFD)

  获得或设置文件状态标志(cmd=F_GETFL|F_SETFL)

  获得或设置异步I/O所有权(cmd=F_GETOWN|F_SETOWN)

  获得或设置记录锁(cmd=F_GETLK|F_SETLK、F_SETLKW)

  可以用fcntl函数设置文件状态,常用设置套接字描述符为非阻塞O_NONBLOCK

  ioctl函数

  #include 《sys/ioctl.h》

  int ioctl(int d, int request, 。。。);

  提供了一个用于控制设备及其描述符行为和配置底层服务的接口。

  /dev/fd

  打开文件/dev/fd/n等效于复制描述符n。

  上面就是Linux文件I/O的相关介绍了,通过这些介绍相信你已经对文件I/O有了进一步的了解,如果你还想了解更多的相关知识的话,不妨多多关注本网站吧。

发表评论

0

没有更多评论了

评论就这些咯,让大家也知道你的独特见解

立即评论

以上留言仅代表用户个人观点,不代表系统之家立场

其他版本软件

热门教程

人气教程排行

Linux系统推荐

扫码关注
扫码关注

扫码关注 官方交流群 软件收录