APUE学习笔记——第三章文件I/O

1、文件描述符:意思就是unix 环境下用open函数打开一个文件,正确执行后会返回个整型数值,这个就叫文件描述符。(个人理解的,解释可能完全不对)

      基本的三种文件描述符:STDIN_FILENO (0)标准输入,STDOUT_FILENO(1) 标准输出,STDERR_FILENO(2) 标准错误输出。

      常量的定义基本上都在<unistd.h>头文件中。

2、函数介绍:

      2.1 open函数

             原型:#include<fcntl.h> 

                         int open(const char *filename, int oflag, mode_t mode) 打开文件

             oflag主要参数:O_RDONLY只读打开,O_WRONLY只写打开,O_RDWR读写打开,O_APPEND每次写入追加到文件末端,O_CREAT打开文件不存在则建立,O_TRUNC若文件存在且以只读或读写打开则将该文件长度截短为0

             可以用open(filename,O_WRONLY|O_TRUNC|O_CREAT,mode)来新建一个文件。

   2.2 creat函数

          #include <fcntl.h> 

          int creat(const char*filename, mode_t mode) 创建新文件

  2.3 close函数

         int close(int filedes)

  2.4 lseek函数

        off_t lseek(int filedes,off_t offset, int whence) 为打开的文件设置偏移量

        whence参数:SEEK_SET(0)偏移量设置为文件开始处offset个字节,SEEK_CUR(1)偏移量设置为当前值加offset,offset正负皆可,SEEK_END(2)偏移量设置为文件长度加offset,正负皆可。

  2.5 read函数

        size_t read(int filedes, void *buf, size_t nbytes) 读取文件中内容

  2.6 write函数

        size_t write(int filedes, const void *buf, size_t nbytes) 将buf中的字符串写到文件中

   

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

int main(){
    char buf[64];
    if(getcwd(buf,sizeof(buf)-1) != NULL)//得到当前文件目录
        printf("%s\n",buf);
    else
        perror("error");
    int fd;
    char filename[128];
    memset(filename,0,sizeof(filename));
    strcat(filename,buf);
    strcat(filename,"/3_1_file.txt");
    printf("%s\n",filename);
    memset(buf,0,sizeof(buf));
    if((fd = open(filename,O_WRONLY | O_CREAT | O_TRUNC,0644)) == -1)//创建新文件
        perror("Can't open file");
    else{
        gets(buf);//等待输入
        write(fd,buf,sizeof(buf));//写入到文件,文件总共64个字节
		 
        off_t of1,of2;
        close(fd);
        if((fd = open(filename,O_RDONLY)) != -1){
              read(fd,buf,64);
              printf("File content: %s\n",buf);
              of1 = lseek(fd,2,SEEK_SET);//从文件开始偏移2个字节
              
              read(fd,buf,64);//读取64个字节,这时文件的偏移量已经到文件末尾了
              printf("File content: %s\n",buf);
              of2 = lseek(fd,-60,SEEK_CUR);//从当前文件位置(即末尾)向前便宜60个字节
              read(fd,buf,64);
              printf("File content: %s\n",buf);
              printf("of1=%d, of2=%d\n",of1,of2);
              close(fd);//关闭文件
        }else{
             perror("Can't open file");
        }
    }
    return 0;
}
如果想查看写入到3_1_file.txt中的文件内容,最好使用od -c ./3_1_file.txt


3、I/O效率

      这个应该是设置BUFFSIZE=系统block大小应该I/O效率是最高的,一般block大小都是4096bytes

4、复制文件描述符函数
       int dup(int fildes);
       int dup2(int fildes, int fildes2);
              dup返回的新文件描述符是当前可用文件描述符中最小值,dup2则是用fildes2参数指定新文件描述符的数值,若fildes2打开则关闭,若fildes等于fildes2则不关闭,返          回fildes2.在CGI程序用dup2将文件描述符重新定位到标准输入和标准输出。即:dup2(fd,STDOUT_FILENO)或dup2(fd,STDIN_FILENO)。

5、sync、fsync、fdatasync函数

     int fsync(int filedes)

     int fdatasync(int filedes)

     void sync(void)

     此三个函数都是将高速缓存中的已经修改的的内容写到硬盘上,用数据库的话说就是防止出现“读脏数据”。

6、改变已打开文件的性质函数:
int fcntl(int fd, int cmd, ... /* arg */ ); //此函数功能很强大
函数功能:
复制一个现有的描述符(cmd=F_DUPFD)
获得或设置文件描述符(cmd=F_GETFD|F_SETFD)
获得或设置文件状态标志(cmd=F_GETFL|F_SETFL)
获得或设置异步I/O所有权(cmd=F_GETOWN|F_SETOWN)
获得或设置记录锁(cmd=F_GETLK|F_SETLK、F_SETLKW)

可以用fcntl函数设置文件状态,常用设置套接字描述符为非阻塞O_NONBLOCK。

        dup(filedes)等价于:fcntl(filedes,F_DUPFD,0)

  dup2(filedes1,filedes2)等价于:close(filedes2)fcntl(filedes,F_DUPFD,filedes2) 唯一的不同是dup2是原子操作

#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc,char* argv[])
{
	int val;
	if(argc != 2)
	{
	   printf("usage: a.out <descriptor#>\n");
	   exit(-1);
	}
	val = fcntl(atoi(argv[1]),F_GETFL,0);
	if(val == -1)
	{
	   perror("fcntl() error");
	   exit(-1);
	}
	switch(val & O_ACCMODE)
	{
	 case O_RDONLY:
		 printf("read only.\n");
		 break;
	 case O_WRONLY:
		 printf("write only\n");
		 break;
	 case O_RDWR:
		 printf("read write.\n");
		 break;
	 default:
		 printf("unknown access mode");
	}
	if(val&O_APPEND)
	  printf(",append");
	if(val&O_NONBLOCK)
	  printf(",nonblocking");
	putchar('\n');
	return 0;
}

7、/dev/fd具体Google一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值