首页
学习
活动
专区
圈层
工具
发布

linux系统下fcntl函数解析与标准IO函数介绍

-----今天是最后一篇文章关于linux系统下文件IO操作了,从明天起开始写文件属性的文章了,欢迎大家来学习,一起进步。(同时也欢迎大家批评指出错误,我会及时纠正过来的)。

一、fcntl函数解析:

1、函数原型:先用man手册来查看fcntl的用法和原型:

int fcntl(int fd, int cmd, ... /* arg */ )

参数解析:

fd:文件描述。

cmd:操作命令。

arg:供命令使用的参数(其实就是我们指定的那个文件描述符数字大小)

2、我们只以一个cmd参数为例--- F_DUPFD (Duplicate the file descriptor fd using the lowest-numbered available file descriptor greater than or equal to arg. This is different from dup2(2), which uses exactly the file descrip‐tor specified. On success, the new file descriptor is returned);这里主要是说F_DUPFD这个cmd的作用是复制文件描述符(作用类似于dup和dup2),这个命令的功能是从可用的fd数字列表中找一个比arg大或者和arg一样大的数字作为oldfd的一个复制的fd,和dup2有点像但是不同。下面是代码示例:

代码语言:javascript
复制
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define FILENAME        "a.txt"
int main(void)
{
    int fd1 = -1, fd2 = -1;
    fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);
    if (fd1 < 0)
    {
            perror("open");
            return -1;
    }
    printf("fd1 = %d.\n", fd1);
    fd2 = fcntl(fd1, F_DUPFD, 5);
    printf("fd2 = %d.\n", fd2);
    close(fd1);
    return -1;
 }

注:fcntl函数的cmd操作命令还有好多,这里只是起一个抛砖引玉的作用,哈哈哈。

二、标准IO介绍:

1、什么是标准IO,什么又是文件IO?

标准IO是C库函数;而文件IO是linux系统的API,API类似于一种接口,是由操作系统提供的(说实话,在这之前,我这个人比较犟,好少会调用api,非得自己写一个函数,这样有的时候累的半死还不一定能够写出来;而直接用官方给的api函数,可以提高开发效率,节省时间,人力,哈哈哈。)

2、库函数比API还有一个优势就是:API在不同的操作系统之间是不能通用的,但是C库函数在不同操作系统中几乎是一样的。【所以C库函数具有可移植性而API不具有可移植性。性能上和易用性上看,C库函数一般要好一些。譬如IO,文件IO是不带缓存的,而标准IO是带缓存的,等到合适的时间,我们的操作系统才会把写在缓冲区里的内容真正搞到下一层去。因此标准IO比文件IO性能要更高(这里的下一层是指硬件层存储区域,而我们的标准IO函数是应用层方面,它先向系统缓冲区操作,然后等待系统里面的write等函数操作,才把数据弄到硬件层上去)。

3、常用标准IO函数介绍:

常见的标准IO库函数有:fopen、fclose、fwrite、fread、ffulsh(刷新标准库函数的缓存,直接写进操作系统的缓冲区中)、fseek(其实在写这个的话,我自己也对这些函数的用法是一脸的懵逼,还是用man手册去查看他们的用法,才稍微基本会用了,所以这里我举一个例子,也是其抛砖引玉的作用);这里以fopen、fclose、fwrite、fread为例:

这里只查看了fopen的使用,更多使用,大家可以用 man 3 + 标准IO函数查看来查看它们各自的具体用法,这里我就不一一介绍了,代码示例:

代码语言:javascript
复制
#include <stdio.h>              // standard input output
#include <stdlib.h>
#include <string.h>
#define FILENAME        "a.txt"
int main(void)
{
    FILE *fp = NULL;
    size_t len = -1;
    //int array[10] = {1, 2, 3, 4, 5};
    char buf[100] = {0};
    fp = fopen(FILENAME, "r+");//r+表示可读可写
    if (NULL == fp)
    {
            perror("fopen");
            exit(-1);
    }
    printf("fopen success. fp = %p.\n", fp);
    // 在这里去读写文件
    memset(buf, 0, sizeof(buf));//清除缓存区buf
    len = fread(buf, 1, 10, fp);
    // The function fread() reads nmemb items of data, each size bytes long, from the stream pointed to by stream, storing them at the location given by ptr.
    printf("len = %ld.\n", len);
    printf("buf is: [%s].\n", buf);

    fclose(fp);
    return 0;
}

下面是写操作的代码演示:

代码语言:javascript
复制
#include <stdio.h>              // standard input output
#include <stdlib.h>
#include <string.h>
#define FILENAME        "a.txt"
int main(void)
{
    FILE *fp = NULL;
    size_t len = -1;
    int array[10] = {3,5,6,6,9};
    fp = fopen(FILENAME, "w+");
    if (NULL == fp)
    {
            perror("fopen");
            exit(-1);
    }
    printf("fopen success. fp = %p.\n", fp);
    // 在这里去读写文件
    len = fwrite(array, sizeof(int), 
  sizeof(array)/sizeof(array[0]), fp);
// sizeof(array)/sizeof(array[0])中sizeo(array)表示总数组的大
 小,sizeof(array[0])表示一个元素的大小,所以整个式子表示数组 
  的元素个数
    //  The function fwrite() writes nmemb items of data, each size bytes long, to the stream pointed to by stream, obtaining them from the location given by ptr.
    printf("len = %ld.\n", len);
    fclose(fp);
    return 0;
}

三、总结:

通过这一段时间的学习,自己已经掌握了基本的文件IO操作了,接下来还是要多多实践来提高自己。

下一篇
举报
领券