APUE(3)---文件I/O (2)
七.函数write
#include <unistd.h>
size_t write(int fd, const void *buf, size_t nbytes);
//若成功,返回已写字节数;若出错,返回-1
对于普通文件,写操作从文件的当前偏移量处开始。如果在打开文件时,制订了O_APPEND选项,则在每次写操作前,将文件偏移量设在文件的当前结尾处。在一次成功之后,该文件偏移量增加实际写的字节数。
八、I/O的效率
大多数文件系统为改善性能都采用某种预读(read ahead)技术。当检测到正进行顺序读取时,系统就试图读入比应用所要求的更多数据,并假想应用很快就会读这些数据。
九、文件共享
UNIX系统支持在不同进程间共享打开文件。内核使用3种数据结构表示打开文件,他们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响:
1.每个进程在进程表中都有一个记录项,记录项中包含一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:a.文件描述符标志(close_on_exec);b。只想一个文件表项的指针
2.内核为所有打开文件维持一张文件表。每个文件表项包含:a.文件状态标志(读、写、添写、同步和非阻塞等);b.当前文件偏移量;c.指向文件v节点表象的指针
3.每个打开文件和设备都有一个v节点结构。v节点包含了文件类型和对此文件进行各种操作函数的指针。对于大多数文件,v节点还包含了该文件的i节点,i节点包含了文件的所有者、文件长度、指向文件实际数据块在磁盘上所在位置的指针,这些信息是在打开文件时从磁盘上读入内存的并且随时可用的。
3-3:打开文件的内核结构
当两个进程同时打开一个文件时,两个进程都获得一个各自的文件表项是因为这可以使每个进程都有它自己的对该文件的当前偏移量,但对一个特定的文件只有一个v节点表项。下面进一步说明:
1.在完成每一个write后,在文件表项中的当前文件偏移量即增加所写入的字节数。如果这导致当前文件偏移量超出了当前文件长度,则将i节点表项中的当前设置成为当前文件偏移量
2.如果用O_APPEND标志打开一个文件,则相应标志也被设置到文件表项的文件状态标志中。每次对这种具有追加写标志的文件执行操作时,文件表项中的当前文件偏移量首先会被i节点表项中的文件长度。这就使得每次写入的数据都追加到文件的当前尾端处。
3.若一个文件用lseek定位到文件当前的尾端,则将文件表项中的当前文件偏移量设置为i节点表项中的当前文件长度(lseek是一次性的,O_APPEND是重复的)
4.lseek函数至修改文件表项中的当前文件偏移量,不进行任何I/O操作。
3-4:两个独立进程各自打开同一个文件
可能有多个文件描述符项指向同一个文件表项(dup函数),fork函数后,此时父进程、子进程各自的每一个打开文件描述符共享同一个文件表项。文件描述符标志只用于一个进程的一个描述符,文件状态标志则应用于指向该给定文件表项的任何进程中的所有描述符。
十、原子操作
一般而言:原子操作(atomic operation)指的是由多步组成的一个操作。如果该操作原子地执行,要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。
1、追加到一个文件
早期的UNIX本没有提供O_APPEND,追加操作只能通过lseek和write两个操作来完成,但是在这两个操作不是原子的,在多个进程同时操作一个文件时,可能发生A进程lseek到文件尾,B进程在文件尾写入了某些数据,这时A进程再写入,就可能覆盖B的数据。UNIX现在提供了O_APPEND操作来解决这个问题,在其内部的lseek和write是原子的,这样就能保证写入一定是结尾处。
2.函数pread和pwrite
与追加不同的是,这是两个读写的加强版
3.创建一个文件
对open函数现有O_CREAT和O_EXCL,当不存在要创建的文件时,创建文件,并成功返回;若文件已经存在,则返回,这是一个原子操作。如果没有这样一个原子操作,那莪们就只能先尝试去open,open失败再去create,但是在这两个操作间隙可能有其他操作创建了相应的文件,从而导致产生错误。
十一、函数dup和dup2
#include <unistd.h>
int dup(int fd);
int dup2(int fd, int fd2);
//若成功,则返回新的文件描述符,若失败,则返回-1
dup每次返回的新文件描述符一定是当前可用文件描述符中的最小值。对于dup2,可以用fd2指定新描述符的值。如果fd2已经打开,则将其关闭。如fd等于fd2,则dup2返回fd2,而不关闭它。够则fd2的FD_CLOEXEC文件描述符标志就被清除,这样fd2在进程调用exec时是打开状态。并且dup和dup2返回的新文件描述符是共享一个文件表项,这就意味着他们共享:文件状态标志、文件偏移量等信息。dup2也是一个原子操作,相当于一个close加fcntl,二者有细微差别。
APUE(3)---文件I/O (2)的更多相关文章
- (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- apue.h文件找不到的解决办法
参考:http://blog.csdn.net/nihaotoyou/article/details/16827675 1.首先到该书的官网下载源代码:http://www.apuebook.com/ ...
- 【APUE】文件I/O
Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descri ...
- [apue] 使用文件记录锁无法实现父子进程交互执行同步
父子进程间交互执行是指用一种同步原语,实现父进程和子进程在某一时刻只有一个进程执行,之后由另外一个进程执行,用一段代码举例如下: SYNC_INIT(); , counter=; pid_t pid ...
- [apue] linux 文件访问权限那些事儿
前言 说到 linux 上的文件权限,其实我们在说两个实体,一是文件,二是进程.一个进程能不能访问一个文件,其实由三部分内容决定: 文件的所有者.所在的组: 文件对所有者.组用户.其它用户设置的权限访 ...
- [11]APUE:(文件)记录锁
[a] 概念 建议锁:在遵循相同记录锁规则的进程间生效,通常用于保证某个程序自身多个进程间的数据一致性 强制锁:意在保证所有进程间的数据一致性,但不一定有效:如不能应对先 unlink 后建立同名副本 ...
- [04]APUE:文件与目录
[a] stat / lstat / fstat #include <sys/stat.h> int stat(const char *restrict pathname, struct ...
- [03]APUE:文件 I/O
[a] open #include <fcntl.h> int open(const char *path, int oflag, ... ,mode_t mode) 成功返回文件描术符, ...
- 重读APUE(5)-文件权限
文件,目录,权限 1. 用名称打开任一个类型的文件时,对该名字中包含的每一个目录,包括它可能隐含的当前工作目录都应该具有执行权限:这就是目录执行权限通常被称为搜索位的原因: 例如:为了打开文件/usr ...
随机推荐
- 关于Android Studio上得处女座福音功能——reformat code
在mac上,选中需要的代码,然后 Option+(shift) + Command + L 全部重新排列!!爽飞!
- linux(centos7) 安装nginx
linux(centos7) 安装nginx 1.14(stable) 版本 Nginx配置文件常见结构的从外到内依次是「http」「server」「location」等等,缺省的继承关系是从外到内, ...
- Eclipse中的maven项目打war包
在对应的pom文件中,找到packing这个属性,改为war:如果没有,就自己加一个,这个是有默认值的,默认为jar. 例如: <modelVersion>4.0.0</modelV ...
- springboot redis简单结合
参考: https://www.cnblogs.com/ityouknow/p/5748830.htmlhttp://blog.csdn.net/i_vic/article/details/53081 ...
- The java.util.concurrent Synchronizer Framework笔记
这篇笔记是关于 Doug Lea 的 The java.util.concurrent Synchronizer Framework . 原文地址:http://gee.cs.oswego.edu/d ...
- java的错误代码。。。。
总结:从键盘输入一组数,输出其最大值,这段代码是错的,因为每次都错在这里,所以自己还是没有理解~~~~ import java.util.Scanner; //键盘输入一组数据,并输出最小值 //从键 ...
- chrome浏览器,调试详解,调试js、调试php、调试ajax
1.可以看到js报错 2.可以看到php报错 3.可以看到ajax返回的信息,以及报错情况 4.可以看到调用了那些内容以及顺序 5.可以调试js代码 6.可以查看session等等 功能非常之强大. ...
- java自己写的简单聊天工具SimpleQQ感悟
Demo如下: 客户端: /* * 一个简单的QQ * 2013-8-1 * @李志杰 */ package SimpleQQ_Client; import java.awt.*; import ja ...
- iis7+的虚拟目录:未能加载程序集“**”。请确保在访问该页之前已经编译了此程序集
在使用win8系统后,突然想运行iis,于是在windows组件中启用iis,并aspnet_regiis.exe -i注册iis后,于是开始发布了一个站点,一切正常 继而,在该站点下添加虚拟目录,然 ...
- 浅谈PL/SQL语言基础
在前面的学习中,我们大部分接触的都是SQL语言,但是,在实现复杂操作的时候,SQL语言就无能为力了,这时候就需要引入新的语言,PL/SQL语言就是对SQL语言的扩展,可以实现存储过程,函数等的创建.下 ...