免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1148 | 回复: 0
打印 上一主题 下一主题

缓冲与非缓冲文件系统的简单描述 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-12-13 14:01 |只看该作者 |倒序浏览
在APUE第三节——File I/O 中,主要描述的是一系列的 I/O 函数,通过一些函数来进行文件的一些操作。
这些操作基本上用下面这几个系统函数:open, read, write, lseek, close。在这一章中所有的系统函数
都属于“非缓冲文件”(unbuffered I/O)。开头第2段文字有这样一句话来描述  "unbuffered" : The term
unbuffered means that each read and write invokes a system call in the kernel. 也就
是说这些函数都是直接调用内核中的系统函数,它完全没有经过“缓冲区”,直接调用了。所以,这样不经过
“缓冲区”速度就肯定比经过“缓冲区”快了。这篇学习笔记将对“缓冲文件系统”和“非缓冲文件系统”作一个
比较,当然,主要还是放在“非缓冲文件系统”方面来描述。
一、缓冲文件系统简要描述:
    第一段简单说到了, “缓冲文件系统”的文件操作要经过“缓冲区”,那么具体如何操作呢?比如说最常用的
read 和 write。首先操作系统会在内存区域开辟一个缓冲区,顾名思义缓冲区就是用于缓冲的。如果要执行
read操作,那么先从磁盘那里把数据内容读入了缓冲区,然后等到把缓冲区装满之后,CPU再从缓冲区把数据
读入特定的变量。如果是写操作,刚好是反过来了,CPU先把数据一个个写进缓冲区里面,等到写满之后就把
缓冲区刚刚写进的数据写入到文件里面了。
    ANSI C 中函数库支持“缓冲区文件系统”, 所以文件操作函数像 fopen, fclose, fread, fwrite等都是
属于缓冲I/O。这里不多说这些函数了。
二、非缓冲文件系统描述:
    在ANSI C 中函数库支持“缓冲区文件系统”,但不支持“非缓冲文件系统”,“非缓冲文件系统”是POSIX.1
和  UNIX specification 的一部分。
    前面说到了,非缓冲I/O是系统直接的输入和输出,它不经过“缓冲区”,所以从速度和效率方面来说就显得
快一些了。下面对几个基本的unbuffered I/O 函数的功能通过配合代码描述一下。
               
               
                1. int open(const char *pathname, int flags);
   int open(const char *pathname, int flags, mode_t mode);   
    man手册上提供的函数原型。pathname 是路径名,是文件打开或者新建的文件名字。参数 flags 是选择
的描述符。man手册上有句话这样描述flags:The  parameter  flags  must  include one of the
following accessmodes:O_RDONLY, O_WRONLY, or O_RDWR. These request opening  the  file  
read-only, write-only,  or  read/write, respectively.还有通过“位与”的模式来描述flags的,man手册上
都写得很具体了。比较上面两个open原型,发现第2个函数原型多了一个参数mode_t mode.有什么区别?  
The argument mode specifies the permissions to use in case a  new  file is created. 所有只有当
是新建文件的时候,第3个参数才有它的作用,在手册上也一几个你列举了这个参数的一些值了。下面这样调用
open 就是等价于新建了一个文件:
open(pathname, O_WRONLY | O_CTREAT | O_TRUNC, mode);
2. ssize_t read(int fd, void *buf, size_t count);
    ssize_t : functions that return a count of bytes(signed).
注意到第1个参数fd, 这是文件的描述符。对于内核来说,所有的文件都用文件描述符来描述。read函数作用:
从文件描述符 fd 中读 count 个字节 进入 buf区。函数执行成功返回读入的字节数,失败的话返回 -1, 并
对 errno 赋予相应的值。
3.ssize_t write(int fd, const void *buf, size_t count);
和  read 函数相反,从 buf 里写count个字节进入文件描述符fd里面。
4.off_t lseek(int fildes, off_t offset, int whence);
off_t : file sizes and offsets(signed);
lseek是随机访问文件函数。这个函数非常重要。因为每次对文件进行读写操作的位置总是在前一次操作之后。
这样有时候要访问文件的其他位置就麻烦了,就得依靠这个函数了。
    fildes:文件描述符;
    offset:访问的文件的位置
    whence:值可以是0,1,2;分别表示从文件开始、从文件当前位置、从文件结束位置;
    返回值:成功就返回新的文件位置,失败返回-1。
5. int close(int fd);
close 很简单,关闭一个文件描述符,这样就这个文件内容就不会被无意修改和使用了。
返回0表示执行成功,返回-1表示执行失败。
6. int creat(const char *pathname, mode_t mode);
用于创建一个新的文件。参数就不说了,参照open函数。 creat函数返回一个新文件描述符。
三、实例简单分析:
实例1:下面的程序是来自Figure 3.2,利用几个基本函数构造而成,非常简单,简单的分析都在注释里面
了;
#include "apue.h"
#include fcntl.h>
char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
int main(void)
{
    int        fd;   
    /*offset is 0 when the file is created.*/
    if ((fd = creat("file.hole", FILE_MODE))  0)
        err_sys("creat error!");
    /*offset is 10 after calling the write function.
    * write 10 bytes form buf1 to fd*/
    if (write(fd, buf1, 10) != 10)
        err_sys("buf1 write error!");
   
    /*offset is 16384 after calling the lseek function*/
    if (lseek(fd, 16384, SEEK_SET) == -1)
        err_sys("lseek error!");   
    /*offset is 16394 because we write 10 bytes form buf2*/
    if (write(fd, buf2, 10) != 10)
        err_sys("write error!");
    exit (0);
}
实例2 :read & write 的配合
#include "apue.h"
int main(void)
{
    int        n;
    char     buf[4096];
    /*read from the stdin file and write to stdout*/
    while ((n = read(STDIN_FILENO, buf, 4096)) > 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");
    if (n  0)
        err_sys("read error");
    exit (0);
}
四、后记
    其实第3章我没全学完,这只是对一部分的学习笔记,等后面的内容学习后再补充上去。由于刚学,
难免写得比较肤浅,而且写这篇文章时间比较紧,可能还有一些认识上的错误,请师傅还有其他一些朋友指
教!
                                                                                                           lj_860603(键键)
                                                                                                                                              2006.12.13


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/27541/showart_214877.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP