七.函数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)的更多相关文章

  1. (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  2. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  3. apue.h文件找不到的解决办法

    参考:http://blog.csdn.net/nihaotoyou/article/details/16827675 1.首先到该书的官网下载源代码:http://www.apuebook.com/ ...

  4. 【APUE】文件I/O

    Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file descri ...

  5. [apue] 使用文件记录锁无法实现父子进程交互执行同步

    父子进程间交互执行是指用一种同步原语,实现父进程和子进程在某一时刻只有一个进程执行,之后由另外一个进程执行,用一段代码举例如下: SYNC_INIT(); , counter=; pid_t pid ...

  6. [apue] linux 文件访问权限那些事儿

    前言 说到 linux 上的文件权限,其实我们在说两个实体,一是文件,二是进程.一个进程能不能访问一个文件,其实由三部分内容决定: 文件的所有者.所在的组: 文件对所有者.组用户.其它用户设置的权限访 ...

  7. [11]APUE:(文件)记录锁

    [a] 概念 建议锁:在遵循相同记录锁规则的进程间生效,通常用于保证某个程序自身多个进程间的数据一致性 强制锁:意在保证所有进程间的数据一致性,但不一定有效:如不能应对先 unlink 后建立同名副本 ...

  8. [04]APUE:文件与目录

    [a] stat / lstat / fstat #include <sys/stat.h> int stat(const char *restrict pathname, struct ...

  9. [03]APUE:文件 I/O

    [a] open #include <fcntl.h> int open(const char *path, int oflag, ... ,mode_t mode) 成功返回文件描术符, ...

  10. 重读APUE(5)-文件权限

    文件,目录,权限 1. 用名称打开任一个类型的文件时,对该名字中包含的每一个目录,包括它可能隐含的当前工作目录都应该具有执行权限:这就是目录执行权限通常被称为搜索位的原因: 例如:为了打开文件/usr ...

随机推荐

  1. VCS (版本控制系统)

    1.什么是VCS? 版本控制系统(version control system),是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.版本控制系统不仅可以应用于软件源代码的文本文件, ...

  2. git学习3 - 克隆远程库到本地 将本地库上传到git

    如何克隆远程版本库到本地 git clone URL 如何用命令将本地项目上传到git 1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 (注意: cd C:/U ...

  3. MFC学习(二)

    WinApp封装了程序的主入口WinMain,WinMain就和C语言的main函数地位一样,是Win32程序的入口.在MFC的封装中,一个程序启动,Windows调用WinMain,这个WinMai ...

  4. 如何查看路由器中的pppoe拨号密码?

    1 2 3 4 5 6 分步阅读 有时候把宽带的账号密码给忘了,进路由器的拨号页面看了一下,账号能看到,就密码是以“*”号形式显示的,没法用“肉眼”识别出来,怎么办呢?难道真的非得打电话问运营商不可? ...

  5. Select/Poll/Epoll异步IO

    IO多路复用 同步io和异步io,阻塞io和非阻塞io分别是什么,有什么样的区别? io模式 对于一次io 访问(以read为例),数据会先拷贝到操作系统内核的缓冲区,然后才会从操作系统内核的缓冲区拷 ...

  6. Java面向对象-类与对象

    Java面向对象-类与对象 类与对象的关系 我们通俗的举个例子,比如人类是一种类,张三这个人就是人类的具体的一个个体,也就是java中的对象:这就是一个类与对象的关系: 类的定义 下面看实例 类的创建 ...

  7. Strom简单介绍

    1.离线计算是什么? 离线计算:批量获取数据.批量传输数据.周期性批量计算数据.数据展示 代表技术:Sqoop批量导入数据.HDFS批量存储数据.MapReduce批量计算数据.Hive批量计算数据. ...

  8. Bootstrap日期插件中文实现

    Bootstrap的相关JS和CSS直接跳过. <script type="text/javascript" src="static/js/jquery-1.9.1 ...

  9. 详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化

    在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子详解这两个函数的作用. 1. ...

  10. JavaScript(JS)实现省市联动选择下拉列表

    在开发一个应用的时候需要用刀省市联动的下拉列表,网上找到不少.但是要么太复杂,难以修改:要么根本就用不了,最后自己在一个示例中提取出数据,然后自己写了一个,简单易懂,适合新手... 代码如下: Pro ...