七.函数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. (转)Android代码混淆-添加了Gson遇到的问题

    折腾了好久.....郁闷 -_- 1.首先,project.properties里的配置文件变了,之前的项目一直都是在project.properties这个文件中添加一行proguard.confi ...

  2. 发现一个github的奇葩设定

    commit时留下的邮箱,会显示在github的提交记录里,然后居然自动找服务器上的这个邮箱注册的人,显示这个用户名.

  3. 使用FormData实现ajax文件异步上传

    1.传统的web开发文件上传一般是基于form表单的文件上传,同步的方式,用户体验差,可控性也差 2.异步上传的实现 有以下方式 2.1 借助浏览器插件 一般需要安装一些类似flash的插件  这种方 ...

  4. java图形用户界面添加背景颜色不成功的解决方案

    总结:背景颜色不成功,那么使用这个方法试试.getContentpane(); package clientFrame; import java.awt.Color; import java.awt. ...

  5. EasyUI treegrid 加载checked

    EasyUI treegrid  加载checked $(function () { $('#tbDictContTree').treegrid({ title: '数据字典目录管理', iconCl ...

  6. MAPREDUCE的实战案例

    reduce端join算法实现 1.需求: 订单数据表t_order: id date pid amount 1001 20150710 P0001 2 1002 20150710 P0001 3 1 ...

  7. leetcode852

    int peakIndexInMountainArray(vector<int>& A) { int Len = A.size(); ; ; i < Len - ; i++) ...

  8. 【知识结构】最强Web认证知识体系

    花了些时间总结了下Web认证,以及各种方式的利弊和使用,后续后继续更新.文章转载请注明出处:https://www.cnblogs.com/pengdai/p/9144843.html -----20 ...

  9. Hadoop编码解码【压缩解压缩】机制详解(1)

    想想一下,当你需要处理500TB的数据的时候,你最先要做的是存储下来.你是选择源文件存储呢?还是处理压缩再存储?很显然,压缩编码处理是必须的.一段刚刚捕获的60分钟原始视屏可能达到2G,经过压缩处理可 ...

  10. java之yield(),sleep(),wait()区别详解-备忘笔记(转)

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁.也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据.注意该方 ...