zoukankan      html  css  js  c++  java
  • lseek,fcntl,ioctl函数

    函数说明:
    每一个已打开的文件都有一个读写位置, 当打开文件时通常其读写位置是指向文件开头, 若是以附加的方式打开文件(如O_APPEND), 则读写位置会指向文件尾. 当read()或write()时, 读写位置会随之增加,lseek()便是用来控制该文件的读写位置. 参数fildes 为已打开的文件描述词, 参数offset 为根据参数whence来移动读写位置的位移数.

    注意其每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。但是有一个例外,如果以O_APPEND方式打开,每次写操作都会在文件末尾追加数据,然后将读写位置移到新的文件末尾。lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)。

    lseek扩展文件:

    touch创建文件test,注意其大小为0:

    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdlib.h>
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    int main(void)
    {
        int fd=open("test",O_RDWR);//假设已经存在test文件并且有读写权限
        if(fd<0)
        {
            perror("open test");
            exit(-1);
        }
        //扩展一个文件,一定要有写操作 0x1000为4096
        lseek(fd,0x1000,SEEK_SET);
        write(fd,"a",1);
    
        close(fd);
        return 0;
    }

    运行结果:

    可以看到文件大小变成了4097,为4096加上我们写入的一个字符a。注意,如果程序中没有write函数进行写操作,test文件大小不会改变。

    lseek获取文件大小: 

    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdlib.h>
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    int main(void)
    {
        int fd=open("hello",O_RDWR);
        if(fd<0)
        {
            perror("open hello");
            exit(-1);
        }
        long long int len;
        //第二个参数到SEEK_END的长度,off_t在64为系统中,通常为long long int,32的为long
       len= lseek(fd,0,SEEK_END);
        printf("%lld
    ",len);
    
        close(fd);
        return 0;
    }

    创建hello文件,写入hello文本,一共6个字符,包含最后一个 .

    输出:

    通过od指令也可以看出大小为6.

    fcntl
    先前我们以read终端设备为例介绍了非阻塞I/O,为什么我们不直接对STDIN_FILENO做
    非阻塞read,而要重新open一遍/dev/tty呢?因为STDIN_FILENO在程序启动时已经被自动
    打开了,而我们需要在调用open时指定O_NONBLOCK标志。这里介绍另外一种办法,可以用
    fcntl函数改变一个已打开的文件的属性,可以重新设置读、写、追加、非阻塞等标志(这
    些标志称为File Status Flag),而不必重新open文件。

    #include <unistd.h>
    #include <errno.h>
    #include <stdlib.h>
    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<sys/ioctl.h>
    int main(void)
    {
        struct winsize size;
        if (isatty(STDOUT_FILENO) == 0)
            {
                 exit(1);
            }
        if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)<0)
         {
             perror("ioctl TIOCGWINSZ error");
             exit(1);
         }
        printf("%d rows, %d columns
    ", size.ws_row, size.ws_col);
        return 0;
    }

    在图形界面的终端里多次改变终端窗口的大小并运行该程序,观察结果。

     没有人是所有内核驱动或者应用函数都记得的,所以很多时候,我们需要借助谷歌必应百度搜索,一点一点积累。

  • 相关阅读:
    ASP.NET中的ViewState
    (标记)Spring.Net+NHibenate+Asp.Net mvc +ExtJs 系列 By 似水流年
    C#中类的定义
    苹果CMS搭建影视网站教程
    Java之冒泡排序
    Java之数组扩容
    Linux之netstat命令基本使用
    Linux之systemctl命令基本使用
    Oracle11g R2 安装教程(非常详细 )
    Linux之firewall防火墙开启和关闭
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/7081479.html
Copyright © 2011-2022 走看看