Linux-笔记 应用编程函数总结

之前一直没做总结,这里总结一下。

一、文件I/O

open

复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
例子:
int fd;
fd = open("./test_kondon", O_WRONLY | O_CREAT | O_EXCL);        

write

复制代码
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
例子:
    int fd1, ret;
    char buffer[50] = "hello world";

    fd1 = open("/src_file", O_RDONLY);
    if (-1 ==  fd1) {
        printf("open src_file error");
        return -1;
    }
  

    ret = write(fd1, buffer, sizeof(buffer));
    if (ret == -1) {
        printf("Error: write dest_file failed!\n");
        goto err1;
    }

    ret = 0;

    close(fd1);
  


err1:
    close(fd1);

read

复制代码
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
例子:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>


int main(int argc, char **argv) {
    
    int fd1, ret;
    char buffer[1024];

    fd1 = open("/src_file", O_RDONLY);
    if (-1 ==  fd1) {
        printf("open src_file error");
        return -1;
    }
    

    ret = lseek(fd1, 500, SEEK_SET);
    if (-1 == ret)
        goto err1;

    ret = read(fd1, buffer, sizeof(buffer));
    if (-1 == ret) {
        printf("Error: read src_file filed!\n");
        goto err1;
    }


    ret = 0;

    close(fd1);


err1:
    close(fd1);
}

close

复制代码
#include <unistd.h>
int close(int fd);

lseek

复制代码
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
//SEEK_SET SEEK_CUR SEEK_END
例子:
int fd1, fd2, ret;
    char buffer[1024];

    fd1 = open("/src_file", O_RDONLY);
    if (-1 ==  fd1) {
        printf("open src_file error");
        return -1;
    }
    
    fd2 = open("/dest_file", O_WRONLY | O_CREAT | O_EXCL | S_IRWXU | S_IRGRP | S_IROTH);
    if (fd2 == -1) {    
        printf("open dest_file error");
        ret = -1;
        goto err1;
    }

    ret = lseek(fd1, 500, SEEK_SET);
    if (-1 == ret)
        goto err2;

    ret = read(fd1, buffer, sizeof(buffer));
    if (-1 == ret) {
        printf("Error: read src_file filed!\n");
        goto err2;
    }

    ret = lseek(fd2, 0, SEEK_SET);
    if (-1 == ret) {
        goto err2;
    }

    ret = write(fd2, buffer, sizeof(buffer));
    if (ret == -1) {
        printf("Error: write dest_file failed!\n");
        goto err2;
    }

    ret = 0;

    close(fd1);
    close(fd2);


err2:
    close(fd2);
err1:
    close(fd1);

perror

复制代码
#include <stdio.h>
void perror(const char *s);
例子:

int fd;

/* 打开文件 */
fd = open("./test_file", O_RDONLY);
if (-1 == fd) {
    perror("open error");
    return -1;
}

close(fd);

return 0;

dup

复制代码
#include <unistd.h>
int dup(int oldfd);
//复制文件描述符

dup2

复制代码
#include <unistd.h>
int dup2(int oldfd, int newfd);
//复制文件描述符

pread & pwrite

复制代码
#include <unistd.h>
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
//先调用lseek再read
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
//先调用lseek再write

fcntl

:fcntl()函数可以对一个已经打开的文件描述符执行一系列控制操作,譬如复制一个文件描述符(与 dup、dup2 作用相同)、获取/设置文件描述符标志、获取/设置文件状态标志等,类似于一个多功能文件描述符管理工具箱

复制代码
  //fcntl()函数可以对一个已经打开的文件描述符执行一系列控制操作,譬如复制一个文件描述符(与 dup、dup2 作用相同)、获取/设置文件描述符标志、获取/设置文件状态标志等,类似于一个多功能文件描述符管理工具箱

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ )
⚫ 复制文件描述符(cmd=F_DUPFD 或 cmd=F_DUPFD_CLOEXEC);
⚫ 获取/设置文件描述符标志(cmd=F_GETFD 或 cmd=F_SETFD);
⚫ 获取/设置文件状态标志(cmd=F_GETFL 或 cmd=F_SETFL);
⚫ 获取/设置异步 IO 所有权(cmd=F_GETOWN 或 cmd=F_SETOWN);
⚫ 获取/设置记录锁(cmd=F_GETLK 或 cmd=F_SETLK);

ioctl

:文件 IO 操作,一般用于操作特殊文件或硬件外设,通过 ioctl 获取 LCD 相关信息等

复制代码
//文件 IO 操作,一般用于操作特殊文件或硬件外设,通过 ioctl 获取 LCD 相关信息等
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

truncate & ftruncate

复制代码
//将普通文件截断为指定字节长度,ftruncate()使用文件描述符 fd 来指定目标文件,truncate()则直接使用文件路径 path 来指定目标文件
//使用 ftruncate()函数进行文件截断操作之前,必须调用 open()函数打开该文件得到文件描述符,并且必
须要具有可写权限,也就是调用 open()打开文件时需要指定 O_WRONLY 或 O_RDWR。调用这两个函数并不会导致文件读写位置偏移量发生改变,所以截断之后一般需要重新设置文件当前的读写位置偏移量
#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

例子:
/* 使用 ftruncate 将 file1 文件截断为长度 0 字节 */
 if (0 > ftruncate(fd, 0)) {
     perror("ftruncate error");
     exit(-1);
 }

 /* 使用 truncate 将 file2 文件截断为长度 1024 字节 */
 if (0 > truncate("./file2", 1024)) {
     perror("truncate error");
     exit(-1);
 }

二、标准I/O

标准 I/O 库函数是构建于文件 I/O ( open() 、 read() 、 write() 、 lseek() 、 close() 等)这些系统调用之上的, 譬如标准 I/O 库函数 fopen() 就利用系统调用 open() 来执行打开文件的操作、 fread() 利用系统调用 read() 来执行读文件操作、fwrite() 则利用系统调用 write() 来执行写文件操作等等。

fopen

复制代码
#include <stdio.h>
FILE *fopen(const char *path, const char *mode);

fclose

复制代码
#include <stdio.h>
int fclose(FILE *stream);

fread

复制代码
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
例子:
    FILE *fp = NULL;
    char buf[50] = {0};
    int size = 0;
    int ret = 0;

    if (NULL == (fp = fopen("./test_file1", "r"))) {
        perror("test_file1 open failed");
        exit(-1);
    }
    ret = fseek(fp, 0, SEEK_END);
    if (ret < 0) {
        perror("test_file1 seek failed");
        fclose(fp);
        exit(-1);
    }

    long fileSize = ftell(fp);
    printf("文件大小:%ld\r\n", fileSize);

    printf("文件打开成功\r\n");


    ret = fseek(fp, 0, SEEK_SET);
    if (ret < 0) {
        perror("test_file1 seek failed");
        fclose(fp);
        exit(-1);
    }

    if (0 > (size = fread(buf, 1, fileSize, fp))) {
        printf("文件读取失败\r\n");
        fclose(fp);
        exit(-1);
    }

    printf("读取到 %d 个数据:%s\r\n", size, buf);

    fclose(fp);
    exit(0);

fwrite

复制代码
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
例子:
    char buf[] = "Hello World\n";
    FILE *fp = NULL;

    if (NULL == (fp = fopen("./test_file1", "w"))) {
        perror("Couldn't open");
        exit(-1);
    }

    printf("文件打开成功");

    if (sizeof(buf) > fwrite(buf, 1, sizeof(buf), fp)) {
        printf("Couldn't write"); 
        fclose(fp);
        exit(-1);
    }

    printf("写入数据成功\n");

    fclose(fp);
    exit(0);

fseek

复制代码
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
例子:
//fseek(file, 0, SEEK_SET);
//fseek(file, 0, SEEK_END);
//fseek(file, 100, SEEK_SET);

    FILE *fp = NULL;
    int ret = 0;
    char read_buf[100] = {0};
    char write_buf[] = "www.example.com\r\n";

    if (NULL == (fp = fopen("./test_file", "w+"))) {
        perror("Couldn't open");
        exit(-1);
    }

    printf("文件打开成功\r\n");

    if (sizeof(write_buf) > fwrite(write_buf, 1, sizeof(write_buf), fp)) {
        printf("Couldn't write");
        fclose(fp);
        exit(-1);
    }

    printf("文件写入成功\r\n");

    if (0 > fseek(fp, 0, SEEK_SET)) {
        perror("FSEEK could");
        fclose(fp);
        exit(-1);
    }

    printf("文件定位头成功\r\n");

    if (sizeof(write_buf) > (ret = fread(read_buf, 1, sizeof(read_buf), fp))) {
        printf("Couldn't read");
        fclose(fp);
        exit(-1);
    }

    printf("读取到 %d 个字符:%s\r\n", ret, read_buf);

    fclose(fp);
    exit(0);

ftell

:获取文件当前的读写位置偏移量

复制代码
#include <stdio.h>
long ftell(FILE *stream);
例子:
/* 获取当前位置偏移量 */
 if (0 > (ret = ftell(fp))) {
     perror("ftell error");
     fclose(fp);
     exit(-1);
 }

feof

:测试参数 stream 所指文件的 end-of-file 标志,如果 end-of-file 标志被设置了,则调用feof()函数将返回一个非零值,如果 end-of-file 标志没有被设置,则返回 0。

复制代码
//当文件的读写位置移动到了文件末尾时,end-of-file 标志将会被设置
#include <stdio.h>
int feof(FILE *stream);
例子:
    FILE *fp = NULL;
    int ret = 0;
    char read_buf[100] = {0};
    char write_buf[] = "www.example.com\r\n";

    if (NULL == (fp = fopen("./test_file", "w+"))) {
        perror("Couldn't open");
        exit(-1);
    }

    printf("文件打开成功\r\n");

    if (sizeof(write_buf) > fwrite(write_buf, 1, sizeof(write_buf), fp)) {
        printf("Couldn't write");
        fclose(fp);
        exit(-1);
    }

    printf("文件写入成功\r\n");

    if (0 > fseek(fp, 0, SEEK_SET)) {
        perror("FSEEK could");
        fclose(fp);
        exit(-1);
    }

    printf("文件定位头成功\r\n");

    while (1) {
        if (sizeof(write_buf) > (ret = fread(read_buf, 1, sizeof(read_buf), fp))) {
            printf("Couldn't read\r\n");
            fclose(fp);
            exit(-1);
        }
        if (feof(fp)) {
            printf("到达文件末尾\r\n");
            break;
        }
    }
    
    printf("读取到 %d 个字符:%s\r\n", ret, read_buf);

    fclose(fp);
    exit(0);

ferror

:测试参数 stream 所指文件的错误标志,如果错误标志被设置了,则调用 ferror()函数将返回一个非零值,如果错误标志没有被设置,则返回 0。

复制代码
#include <stdio.h>
int ferror(FILE *stream);
例子:
    FILE *fp = NULL;
    int ret = 0;
    char read_buf[100] = {0};
    char write_buf[] = "www.example.com\r\n";

    if (NULL == (fp = fopen("./test_file", "w+"))) {
        perror("Couldn't open");
        exit(-1);
    }

    printf("文件打开成功\r\n");

    if (sizeof(write_buf) > fwrite(write_buf, 1, sizeof(write_buf), fp)) {
        printf("Couldn't write");
        fclose(fp);
        exit(-1);
    }

    printf("文件写入成功\r\n");

    if (0 > fseek(fp, 0, SEEK_END)) {
        perror("FSEEK could");
        fclose(fp);
        exit(-1);
    }

    printf("文件定位头成功\r\n");

    while (1) {
        if (sizeof(write_buf) > (ret = fread(read_buf, 1, sizeof(read_buf), fp))) {
            if (ferror(fp)) {
                printf("Couldn't read");
                fclose(fp);
                exit(-1);
            }
        }
        
        if (feof(fp)) {
            printf("到达文件末尾\r\n");
            break;
        }
    }
    
    printf("读取到 %d 个字符:%s\r\n", ret, read_buf);

    fclose(fp);
    exit(0);

clearerr

:清除 end-of-file 标志和错误标志,当调用 feof()或 ferror()校验这些标志后,通常需要清除这些标志,避免下次校验时使用到的是上一次设置的值,此时可以手动调用 clearerr()函数清除标志。

复制代码
#include <stdio.h>
void clearerr(FILE *stream);
例子:
    FILE *fp = NULL;
    int ret = 0;
    char read_buf[100] = {0};
    char write_buf[] = "www.example.com\r\n";

    if (NULL == (fp = fopen("./test_file", "w+"))) {
        perror("Couldn't open");
        exit(-1);
    }

    printf("文件打开成功\r\n");

    if (sizeof(write_buf) > fwrite(write_buf, 1, sizeof(write_buf), fp)) {
        printf("Couldn't write");
        fclose(fp);
        exit(-1);
    }

    printf("文件写入成功\r\n");

    if (0 > fseek(fp, 0, SEEK_SET)) {
        perror("FSEEK could");
        fclose(fp);
        exit(-1);
    }

    printf("文件定位头成功\r\n");

    while (1) {
        if (sizeof(write_buf) > (ret = fread(read_buf, 1, sizeof(read_buf), fp))) {
            printf("Couldn't read\r\n");
            fclose(fp);
            exit(-1);
        }
        if (feof(fp)) {
            printf("到达文件末尾1\r\n");
            clearerr(fp); //清除标志,后面的输入输出操作继续进行

            if (feof(fp)) {
                printf("到达文件末尾2\r\n");
            }
            
            break;
        }
    }
    
    printf("读取到 %d 个字符:%s\r\n", ret, read_buf);

    fclose(fp);
    exit(0);

格式化I/O:格式化输出

复制代码
#include <stdio.h>
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int dprintf(int fd, const char *format, ...);
int sprintf(char *buf, const char *format, ...);
int snprintf(char *buf, size_t size, const char *format, ...);

printf("Hello World!\n");
//格式化数据写入到由 FILE 指针指定的文件中
fprintf(stderr, "Hello World!\n");
//格式化数据写入到由文件描述符 fd 指定的文件中
dprintf(STDERR_FILENO, "Hello World!\n");
//格式化数据存储在由参数 buf 所指定的缓冲区中
char buf[100];
sprintf(buf, "Hello World!\n");

char buf[20] = {0};
sprintf(buf, "%d", 100);
格式控制字符串****format
复制代码
printf("转换说明 1 转换说明 2 转换说明 3", arg1, arg2, arg3);

转换说明:%[flags][width][.precision][length]type
%(必选)
flags:标志,可包含 0 个或多个标志;
width:输出最小宽度,表示转换后输出字符串的最小宽度;
precision:精度,前面有一个点号" . ";
length:长度修饰符;
type:转换类型,指定待转换数据的类型。(必选)

例子:
    int a = 0, b = 0, c = 0;
    char buf[50] = {0};

    printf("%d (%s) %d (%s)\n", 520, "Tux", 1314, "xuT");          

    fprintf(stdout, "%d (%s) %d (%s)\n", 520, "Tux", 1314, "xuT");        

    dprintf(STDOUT_FILENO, "%d (%s) %d (%s)\n", 520, "Tux", 1314, "xuT");

    sprintf(buf, "%d (%s) %d (%s)\n", 520, "Tux", 1314, "xuT");
    printf("%s", buf);

    memset(buf, 0x00, sizeof(buf));
    snprintf(buf, sizeof(buf), "%d (%s) %d (%s)\n", 520, "Tux", 1314, "xuT");
    printf("%s", buf);

    exit(0);

格式化I/O:格式化输入

复制代码
#include <stdio.h>

//scanf()函数可将用户输入(标准输入)的数据进行格式化转换
int scanf(const char *format, ...);

//fscanf()函数从 FILE 指针指定文件中读
取数据,并将数据进行格式化转换
int fscanf(FILE *stream, const char *format, ...);

//sscanf()函数从参数 str 所指向的字符串中读取数据,并将数据进行格式
化转换。
int sscanf(const char *str, const char *format, ...);

例子:

int a, b, c;
scanf("%d %d %d", &a, &b, &c);

int a, b, c;
fscanf(stdin, "%d %d %d", &a, &b, &c);

char *str = "5454 hello";
char buf[10];
int a;
sscanf(str, "%d %s", &a, buf);

fsync

**:**fsync()函数,对目标文件的数据进行了同步操作,将参数 fd 所指文件的内容数据和元数据写入磁盘,只有在对磁盘设备的写入操作完成之后,fsync()函数才会返回。

复制代码
#include <unistd.h>
int fsync(int fd);

fdatasync

:将参数 fd 所指文件的内容数据写入磁盘,并不包括文件的元数据;同样,只有在对磁盘设备的写入操作完成之后,fdatasync()函数才会返回

复制代码
#include <unistd.h>
int fdatasync(int fd);

sync

:将所有文件 I/O 内核缓冲区中的文件内容数据和元数据全部更新到磁盘设备中,该函数没有参数、也无返回值,意味着它不是对某一个指定的文件进行数据更新,而是刷新所有文件 I/O 内核缓 冲区。

复制代码
#include <unistd.h>
void sync(void);

内核缓冲标志

复制代码
O_DSYNC:在调用 open()函数时,指定 O_DSYNC 标志,其效果类似于在每个 write()调用之后调用 fdatasync()函数进行数据同步。譬如:
fd = open(filepath, O_WRONLY | O_DSYNC);


O_SYNC:在调用 open()函数时,指定 O_SYNC 标志,使得每个 write()调用都会自动将文件内容数据和元数据刷新到磁盘设备中,其效果类似于在每个 write()调用之后调用 fsync()函数进行数据同步,譬如:
fd = open(filepath, O_WRONLY | O_SYNC);

fileno

:将标准 I/O 中使用的 FILE 指针转换为文件 I/O 中所使用的文件描述符

复制代码
#include <stdio.h>
int fileno(FILE *stream);

fdopen

:将 文件 I/O 中所使用的文件描述符转换成标准 I/O 中使用的 FILE 指针

复制代码
#include <stdio.h>

FILE *fdopen(int fd, const char *mode);
相关推荐
成都蜀味缘餐饮技术培训学校6 小时前
手撕烤兔技术培训实战指南,秘制腌料配方比例与调制手法
大数据·经验分享·笔记·其他·微信公众平台
希和20278 小时前
免费AI视频生成工具汇总(国内优先,适合做漫剧、短视频,Obsidian笔记版)
人工智能·笔记·音视频
且从容.8 小时前
ubuntu安装flink
linux·ubuntu·flink
蒸蒸yyyyzwd9 小时前
秋招学习笔记 day109
笔记·八股
爱和冰阔落9 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨9 小时前
WSL2的安装与使用
linux·wsl
微小的鱼10 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng10 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮11 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
只愿云淡风清11 小时前
正则表达式学习笔记 02:基础语法
笔记·学习·正则表达式