unix 环境高级编程-3-文件I/O(3.1~3.9)

3.2文件描述符

       对内核而言,所有打开的文件都通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或者创建一个新文件时,内核向进城返回一个文件描述符。当读或者写一个问一个文件时候,使用open或者create返回文件描述符标识该文件。将其作为参数传递给read或者write。

    unix系统shell使用文件描述符0与进城的标准输入相关联。文件描述符1与标准输出有关联。文件描述符2与标准出错输出相关联。

      #define 0 STDIN_FILENO
      #define 1 STDOUT_FILENO
      #define 2 STDERR_FILENO

文件描述符的范围0~OPEN_MAX,目前都将其增至63.

3.3open函数

调用open函数可以打开或者创建一个文件。

#include <fcntl.h>

int open(const char* pathname,int oflag,...);


  ...表示仅当创建新文件时候才使用第三个参数。              

    pathname 表示打开或者创建的文件名字  。oflag参数可用来说明此函数的多个选项。有如下常量 O_RDONLY(只读 0),O_WRONLY(只写1),O_RDWR(读写打开 2)  。     上述三个参数必须指定切只能指定一个

下边的参数是可选的。O_APPEND ,每次写的时候追加到尾端。O_CREATE,创建文件,但是mode要指定访问权限。O_EXCL,判断是否文件存在。。。。。还有许多参数请参考http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_1.html

 

同步输入输出:O_DSYNC ,O_RSYNC,O_SYNC

 

由open返回的文件描述符一定是最小的未使用的描述符数值。

3.4create函数

也可以调用create创建一个新文件。

#include<fcntl.h>
int create(const char* pathname,mode_t mode);

返回值,若成功,则返回为只写打开的文件描述符,若出错,则返回-1;

此函数相当于open(path那么,O_WRONLY|O_CREAT|O_TRUNC,mode);

3.5close 函数

#include<unistd.h>
int close(int fileds);

关闭文件,若成功返回0,不成功返回-1;

3.6lseek函数
每打开的文件都有一个与其相关连的“当前文件偏移量”,通常是非负整数。通常读写操作都是从偏移量开始的。系统默认情况下打开文件时,偏移量为0,当设置O_APPEND。

实例

#include "apue.h"

int main(void)
{
        if(lseek(STDIN_FILENO,0,SEEK_CUR)==-1)
                printf("cannot seek\n");
        else
                printf("seek ok\n");
        exit(0);

}
 


运行结果

 

lseek 将当前文件的的偏移量记录在内核中,他并不引起任何I/O。然后该偏移量用户下一个读写操作。文件偏移量可以大于文件的当前长度,在这种情况下,对该文件的下一次系将加长该文件。并在文件中构成一个空洞。位于文件中并没有写过的字节都被度为0.

#include "apue.h"
#include "fcntl.h"

char buf1[]="abcdefghij";
char buf2[]="ABCDEFGHIJ";

int main(void)
{
        int fd;
        if(fd=creat("file.hole",FILE_MODE)<0)
                err_sys("create error");
        if(write(fd,buf1,10)!=10)
                err_sys("buf1 write error");
        if(lseek(fd,16384,SEEK_SET)==-1)
                err_sys("lseek error");
        if(write,(fd,buf2,10)!=10)
                err_sys("lseek error");
        exit(0);



}


运行结果

 

空洞文件是存在的。

 

3.7read 函数

调用read函数从打开的文件中读取数据。

#include<unistd.h>

ssize_t read(int filedes,void* buf,size_t nbytes);


若成功则返回读到的字节数,若以到文件结尾则返回0,若出错则返回-1;

 

经典定义:首先,void*表示通用指针

                 其次,返回值必须是带符号整数。ssize_t,已返回字节数,0,-1

                 第三个参数不带符号,这允许一个16为的实现一次读写数据大65534个字节。

 

3.8 write函数

调用write函数向打开的文件写数据   

#include<unistd.h>

ssize_t write( int fileds,const void* buf,size_t nbytes);

 

成功返回已经写的字节,失败返回-1;

 

3.9 I/O效率
  

示例:将标准输入复制到标准输出

#include "apue.h"
#define BUFFSIZE 4096 

int main(void)
{
        int n;
        char buf[BUFFSIZE];

        while((n=read(STDIN_FILENO,buf ,BUFFSIZE))>0)
                if(write(STDOUT_FILENO,buf,n)!=n)
                err_sys("write error");

        if(n<0)
           err_sys("read error");

        exit(0);


}


书中有对此程序的测试,BUFFSIZE 设置从1到524288,系统CPU时间最小为4096,当逐渐增大,时间又变长了,但变化很小。

                                                                                  

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值