unix环境高级编程.chapter3.1

来源:互联网 发布:长春网络维护 编辑:程序博客网 时间:2024/05/17 06:44

最近导师给的活有点坎坷,周末继续来学学apue。。。

废话不多说。

第一章答案看到一个写的较详细地就转载了,第二章跳过。


I/O 5个基本函数:open,read,write,lseek和close
这章大部分被称为unbuffered I/O 与第五章对照。
涉及在多个进程间共享资源,原子操作的概念就变得很重要。

原子(atomic operation)操作:由多步组成的一个操作。如果该操作原子地执行,则要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。
比如:创建和测试就组成一个原子操作。
             O_CREAT 和 O_EXCL如果在open中同时使用就会报错。

文件描述符: 

内核都用文件描述符引用文件。
open或者creat返回的文件描述符标识该文件,将其作为参数传递给read或者write。
幻数0.1.2分别对应--STDIN_FILENO. STDOUT_FILENO. STDERR_FILENO
#include <fcntl.h>int open(const char *path, int oflag, ... /* mode_t mode */ );int openat(int fd, const char *path, int oflag, ... /* mode_t mode */ ); 
  path是要打开或者创建的名字,oflag是多个选项。
  返回的文件描述符一定是最小的未用的文件描述符。
  而下面这个opennat就是为了能够在path是相对路径名时,fd作为相对路径名在文件系统的开始地址来使用(fd通过打开相对路径名所在的目录获取的。)这个fd还有一个用途,当它是AT_FDCWD时,路径名从当前目录获取。
这样做的目的1.可以使用相对路径名打开目录中的文件。
                         2.避免TOCTTOU错误,这个是因为两个基于文件的函数调用,他们两个没有组成原子操作,那么就容易出错,甚至有的会通过第一次调用降低文件权限,好制造安全漏洞。这就是信息安全地内容了。。。

#include <fcntl.h>int creat(const char *path, mode_t mode);Returns: file descriptor opened for write-only if OK, −1 on error
等效于open(path, O_WRONLY | O_CREAT | O_TRUNC,mode);
#include <unistd.h>int close(int fd);Returns: 0 if OK, −1 on error

#include <unistd.h>off_t lseek(int fd, off_t offset, int whence);//Returns: new file offset if OK, −1 on error
返回新的偏移量,出错返回-1
whence是SEEK_SET/SEEK_CER/SEEK_END分别对应0.1.2分别对应(开始处、当前值、文件长度)加offset
offset可正可负

还可以调用
off_t currpos;
currpos=lseek(fd,0,SEEK_CUR);
得到当前偏移量哦

当前偏移量可能为负,所以最好只测试它是否为-1.只有-1代表为错,不要测试是否小于0。

空洞不占内存。一大堆就说了这一个事情。

READ、WRTIE


#include <unistd.h>ssize_t read(int fd, void *buf, size_t nbytes);Returns: number of bytes read, 0 if end of file, −1 on error

#include <unistd.h>ssize_t write(int fd, const void *buf, size_t nbytes);Returns: number of bytes written if OK, −1 on error

这里的const是因为,避免在write过程中有一些坏人(其他进程或者进程中其他线程)企图改变写缓冲区的内容。

I/O效率

就说4096是比较合适的。以为内这个文件系统磁盘块长度为4096.

3句新知识:

1.对UNIX系统内核而言,文本文件和二进制代码文件并无区别。

2.预读技术:系统检测到你正在顺序读取,就试图读入比当前应用所要求的更多的数据,并且假想应用很快聚会读这些数据。

3.第一次运行使得文件进入高速缓存,后续直接从高速缓存读,无须读写磁盘。但是作者考虑到啦~~~反正我是没想到。。不好意思说自己是学过计算机硬件的。

文件共享

感觉最重要的一部分了。



dup和dup2

#include <unistd.h>int dup(int fd);int dup2(int fd, int fd2);Both return: new file descriptor if OK, −1 on error

sync,fsync, andfdatasyncFunctions

        正常系统都延迟写,但是当缓冲区需要空时,就把所有延迟写的数据写进去磁盘。就调用这3个

#include <unistd.h>int fsync(int fd);//对fd打开的文件起作用,废话。。等待写磁盘结束,并且等待文件属性更新。这样适用于多人读写数据库int fdatasync(int fd);//不等待文件属性更新                       Returns: 0 if OK, −1 on errorvoid sync(void);//把延迟写的数据排入写队列就走了,很不负责任。。程序员可不能这样哦

函数fcntl

#include <fcntl.h>int fcntl(int fd, int cmd, ... /* int arg */ );                                           Returns: depends on cmd if OK (see following), −1 on error
f c n t l函数有五种功能:
复制一个现存的描述符(c m dF _ D U P F D)。
获得/设置文件描述符标记c m d = F _ G E TF DF _ S E T F D)。
获得/设置文件状态标志c m d = F _ G E T F LF _ S E T F L)。
获得/设置异步I / O有权(c m d = F _ G E TO W NF _ S E TO W N)。
获得/设置记录锁(c m d = F _ G E T L K , F _ S E T L KF _ S E T L K W)。

剩下的感觉就是很少用的,先不写了,以后看到了它的作用再补吧。先去取快递了。。。
0 0
原创粉丝点击