【北京迅为】《iTOP-3588开发板系统编程手册》第4章 目录IO和文件属性

RK3588是一款低功耗、高性能的处理器,适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用,RK3588支持8K视频编解码,内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP,内置NPU,支持INT4/INT8/INT16/FP16混合运算能力,支持安卓12和、Debian11、Build root、Ubuntu20和22版本登系统。了解更多信息可点击迅为官网   

【粉丝群】824412014

【实验平台】:迅为RK3588开发板

【内容来源】《iTOP-3588开发板系统编程手册》

【全套资料及网盘获取方式】联系淘宝客服加入售后技术支持群内下载

【视频介绍】:【强者之芯】 新一代AIOT高端应用芯片 iTOP -3588人工智能工业AI主板


第4章 目录IO和文件属性

第2章和第3章的内容都是文件操作相关的,主要包括文件的打开、关闭、读写等操作,在本章节首先对目录相关的系统调用进行讲解,然后对文件属性相关的系统调用API进行讲解。

4.1创建目录

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\15”目录下,如下图所示:

学习前的疑问:

1.创建文件要使用哪个系统调用呢?

2.mkdir()函数要怎样进行使用?

mkdir()用来创建一个目录,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

2

#include <sys/stat.h>

#include <sys/types.h>

int mkdir(const char *pathname, mode_t mode);

mkdir()执行成功会返回0,出错时返回-1。并设置error值

mkdir()函数参数含义如下所示:

参数名称

参数含义

pathname

路径和文件名

2

mode

权限掩码,对不同用户和组设置可执行,读,写权限,使用八进制数表示,此参数可不写。

mkdir的使用较为简单,至此关于mkdir()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

使用mkdir()函数创建一个名为test的文件夹。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo15_mkdir.c文件,如下图所示:

vim demo15_mkdir.c

然后向该文件中添加以下内容 

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
    int ret;                     // 声明一个整型变量,用于保存函数返回值
    if (argc != 2)             // 判断命令行参数是否正确,如果不正确,则输出提示信息并返回-1
    {
        printf("Usage:%s <name file>\n", argv[0]);
        return -1;
    }
    ret = mkdir(argv[1], 0666);  // 创建目录,使用指定的权限
    if (ret < 0)                 // 如果创建目录失败,返回-2,输出错误信息
    {
        perror("mkdir is error\n");
        return -2;
    }
    printf("mkdir is ok\n");     // 输出创建目录成功的提示信息
    return 0;                    // 返回0,表示程序运行成功
}

上述代码用到了main()函数来进行参数的传递,argv[1]参数来设置创建的文件夹名称,第14行用到了mkdir()函数,第一个参数就是要创建的文件夹名称,第二个参数为创建的文件夹权限,最后根据mkdir()函数的返回值来判断目录是否创建。

保存退出之后,使用以下命令对demo15_mkdir.c进行编译,编译完成如下图所示:

gcc -o demo15_mkdir demo15_mkdir.c

可以看到程序运行成功之后,mkdir is ok被打印,然后查看文件夹内容发现test文件已经被成功创建了。

4.2打开和关闭目录

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\16”目录下,如下图所示:

学习前的疑问:

1.目录的打开和关闭要使用哪个系统调用呢?

2.opendir()函数和closedir()函数要怎样进行使用?

在Linux操作系统中使用opendir()打开指定的目录,使用closedir()函数关闭目录流。所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <sys/types.h>

#include <dirent.h>

DIR *opendir(const char *name);

2

int closedir(DIR *dirp);

opendir调成功返回打开的目录流,失败返回 NULL,closedir 调用成功返回0,调用失败返回-1,两个函数的相关参数含义如下所示 

参数名称

参数含义

name

路径名字。

2

dirp

要关闭的目录流指针。

至此,关于打开和关闭目录的系统调用API函数就讲解完成了,下面进行相应的实验。

实验要求:

使用打开opendir()函数打开指定的目录,然后使用closedir()关闭目录。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo16_dir.c文件,如下图所示:

vim demo16_dir.c

然后向该文件中添加以下内容: 

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>

int main(int argc, char *argv[])
{
    int ret;
    DIR *dp;                        // 声明一个指向DIR结构体的指针
    if (argc != 2)                  // 判断命令行参数是否正确,如果不正确,则输出提示信息并返回-1
    {
        printf("Usage:%s <name file>\n", argv[0]);
        return -1;
    }
    dp = opendir(argv[1]);          // 打开指定的目录
    if (dp == NULL)                 // 如果打开目录失败,返回-1,输出错误信息
    {
        perror("opendir is error\n");
        return -1;
    }
    printf("opendir is ok\n");      // 输出打开目录成功的提示信息
    closedir(dp);                   // 关闭打开的目录流
    return 0;                       // 返回0,表示程序运行成功
}

述代码同样用到了main()函数来进行参数的传递,第17行调用了opendir()函数来打开文件夹,argv[1]参数来设置要打开的文件夹名称,第24行用到了closedir()函数,来对目录进行关闭。

保存退出之后,使用以下命令对demo16_dir.c进行编译,编译完成如下图所示:

gcc -o demo16_dir demo16_dir.c

然后使用命令“mkdir test”来创建测试文件夹test,创建完成如下图所示: 

然后使用命令“./demo16_dir ./test”来运行,运行成功如下图所示:

可以看到程序运行成功之后,对应的test文件夹被打开,“opendir is ok”就被成功打印了。

4.3读取目录内容

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\17”目录下,如下图所示:

学习前的疑问:

1.读取目录内容使用哪个系统调用呢?

2.readdir()函数要怎样进行使用?

readdir()函数用于读取打开的目录中的文件和子目录,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

函数返回指向dirent类型结构体的指针,该结构体包含了文件和子目录的信息,如文件名、文件类型等,失败返回 NULL

readdir()函数参数含义如下所示:

参数名称

参数含义

1

dirp

即指向DIR类型结构体的指针dirp,该指针通常是由opendir函数返回的

至此关于readdir()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过readdir()函数读取test目录的目录信息。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo17_readdir.c文件,如下图所示:

vim demo17_readdir.c

然后向该文件中添加以下内容: 

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>

int main(int argc, char *argv[])
{
    int ret;
    DIR *dp;                    // 声明一个指向DIR结构体的指针
    struct dirent *dir;         // 声明一个指向dirent结构体的指针
    if (argc != 2)           // 判断命令行参数是否正确,如果不正确,则输出提示信息并返回-1
    {
        printf("Usage:%s <name file>\n", argv[0]);
        return -1;
    }
    dp = opendir(argv[1]);      // 打开指定的目录
    if (dp == NULL)             // 如果打开目录失败,返回-2,输出错误信息
    {
        perror("opendir is error\n");
        return -2;
    }
    printf("opendir is ok\n");  // 输出打开目录成功的提示信息
    
    while (1)                   // 循环遍历目录中的所有文件
    {
        dir = readdir(dp);      // 读取目录下的一个文件
        if (dir != NULL)        // 如果文件读取成功
        {
            printf("file name is %s\n", dir->d_name);  // 输出文件名
        }
        else                    // 文件读取失败
            break;              // 跳出循环
    }
    closedir(dp);               // 关闭打开的目录流
    return 0;                   // 返回0,表示程序运行成功
}

上述内容和4.2小节相比,添加了一个while循环,会调用27行的readdir()函数进行目录信息的读取,读取完成之后跳出循环,调用closedir()函数对目录进行关闭。

保存退出之后,使用以下命令对demo17_readdir.c进行编译,编译完成如下图所示:

gcc -o demo17_readdir demo17_readdir.c

随后我们使用以下命令建立test测试文件夹,然后在test文件夹下建立test1文件,如下图所示:

mkdir test

cd test/

touch test1

 然后使用命令“./demo17_readdir ./test”来运行,运行成功如下图所示:

可以看到已经成功读取到了test目录下的子目录。

4.4综合练习(二)

本小节完整代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\18”目录下,如下图所示:

实验要求

在综合练习1的基础上,利用我们本阶段学习的知识,修改综合练习1的代码,增加以下需求:

1.打印我们要拷贝的目录下的所有文件名,并拷贝我们需要的文件。

2.通过键盘输入我们要拷贝的文件的路径和文件名等信息

实验过程:

首先进入到ubuntu的终端界面输入以下命令来创建demo18_test.c文件,如下图所示:

vim demo18_test.c

然后向该文件中添加以下内容: 

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>

int main(int argc, char *argv[])
{
    // 步骤一:定义变量
    int fd_src;                 // 源文件描述符
    int fd_obj;                 // 目标文件描述符
    char buf[32] = {0};         // 缓冲区
    char file_path[32] = {0};   // 文件路径
    char file_name[32] = {0};   // 文件名字
    ssize_t ret;                // 读取的字节数
    struct dirent *dir;         // 目录项
    DIR *dp;                    // 目录流指针

    // 步骤二:从键盘输入文件路径
    printf("Please enter the file path:\n");
    scanf("%s", file_path);

    // 步骤三:打开目录,获得目录流指针,并读取目录
    dp = opendir(file_path);    // 打开目录
    if (dp == NULL)
    {
        perror("opendir is error\n");
        return -1;
    }
    printf("opendir is ok\n");  // 输出提示信息
    while (1)                   // 循环读取目录项
    {
        dir = readdir(dp);      // 读取一个目录项
        if (dir != NULL)        // 如果目录项存在
        {
            printf("file name is %s\n", dir->d_name); // 输出目录项的名字
        }
        else                    // 如果目录项不存在
            break;              // 跳出循环
    }

    // 步骤四:获得文件的名字
    printf("Please enter the file name:\n");
    scanf("%s", file_name);

    // 步骤五:获得文件描述符
    fd_src = open(strcat(strcat(file_path, "/"), file_name), O_RDWR);  // 打开源文件
    if (fd_src < 0)
    {
        perror("open is error\n");
        return -2;
    }
    fd_obj = open(file_name, O_CREAT | O_RDWR, 0666);   // 打开或创建目标文件
    if (fd_obj < 0)
    {
        printf("open is error\n");
        return -3;
    }

    // 步骤六:读写操作
    while ((ret = read(fd_src, buf, 32)) != 0)    // 循环读取源文件
    {
        write(fd_obj, buf, ret);                 // 将读取到的数据写入目标文件
    }

    // 步骤七:关闭目录和文件
    close(fd_src);
    close(fd_obj);
    closedir(dp);
    return 0;
}

保存退出之后,使用以下命令对 demo18_test.c进行编译,编译完成如下图所示:

gcc -o  demo18_test  demo18_test.c

随后我们使用以下命令建立test测试文件夹,然后在test文件夹下建立test1、test2、test3三个文件,如下图所示:

mkdir test

cd test/

touch test1

touch test2

touch test3

  然后使用命令“./demo18_test”来运行,随后根据提示输入对应的路径和要复制的文件,运行成功如下图所示:

可以看到test1文件已经被成功复制到了当前目录下。

4.5获取文件属性

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\19”目录下,如下图所示:

学习前的疑问:

1.获取文件属性要使用哪个系统调用呢?

2.stat()函数要怎样进行使用?

stat()函数用来获取文件属性,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

 #include <sys/types.h>

 #include <sys/stat.h>

 #include <unistd.h>

 int stat(const char *pathname, struct stat *buf);

成功返回 0;失败返回-1,并设置 error。

stat()函数参数的含义如下所示:

参数名称

参数含义

pathname

指定需要查看属性的文件路径。

2

buf

调用 stat 函数的时候需要传入 struct stat 变量的指针,获取到的文件属性信息就记录在 struct stat 结构体中。

struct stat结构体中的所有元素加起来构成了文件的属性信息,结构体内容如下所示: 

struct stat
{
	dev_t st_dev; /* 文件所在设备的 ID */
	ino_t st_ino; /* 文件对应 inode 节点编号 */
	mode_t st_mode; /* 文件对应的模式 */
	nlink_t st_nlink; /* 文件的链接数 */    
	uid_t st_uid; /* 文件所有者的用户 ID */
	gid_t st_gid; /* 文件所有者的组 ID */
	dev_t st_rdev; /* 设备号(指针对设备文件) */
	off_t st_size; /* 文件大小(以字节为单位) */
	blksize_t st_blksize; /* 文件内容存储的块大小 */
	blkcnt_t st_blocks; /* 文件内容所占块数 */
	struct timespec st_atim; /* 文件最后被访问的时间 */
	struct timespec st_mtim; /* 文件内容最后被修改的时间 */
	struct timespec st_ctim; /* 文件状态最后被改变的时间 */
};

 至此关于stat()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

使用stat()函数获取文件大小和 inode 编号并打印。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo19_stat.c文件,如下图所示:

vim demo19_stat.c

然后向该文件中添加以下内容: 

#include <sys/types.h>   
#include <sys/stat.h>   
#include <unistd.h>     
#include <stdio.h>       
#include <stdlib.h>      

int main(int argc, char *argv[])
{
    struct stat file_stat;  // 声明一个用来存储文件状态的结构体变量
    int ret;                // 声明一个用来存储函数返回值的变量
    ret =stat("./test", &file_stat);   // 调用 stat 函数获取文件状态信息,并将结果存储到结构体变量中
    if (-1 == ret)         // 判断函数是否执行成功
    {
         printf("stat error");  // 如果执行失败,输出错误信息
         return -1;              // 并返回 -1
    }
    // 如果执行成功,输出文件大小和 inode 号
    printf("file size: %ld bytes\r\n inode number: %ld\n", file_stat.st_size,file_stat.st_ino);
    return 0;  // 返回 0,表示程序正常结束
}

第12行调用了stat()函数将文件属性保存到了file_stat结构体中,在第19行对结构体中的inode值和size大小进行打印。

保存退出之后,使用以下命令对 demo19_stat.c 进行编译,编译完成如下图所示:

gcc -o demo19_stat demo19_stat.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

hello world!!

添加完成如下图所示:

 

保存退出之后,使用“ls -li”命令查看文件属性,如下图所示:

可以看到inode值为30155639,大小为14。然后使用命令“./demo19_stat”来运行,运行成功如下图所示:

可以看到程序运行成功之后,打印出了文件大小和inode值。

4.6检查文件权限

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\20”目录下,如下图所示:

学习前的疑问:

1.检查文件权限要使用哪个系统调用呢?

2.access()函数要怎样进行使用?

access()函数用来对文件权限进行检查,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <unistd.h>

int access(const char *pathname, int mode);

 检查项通过则返回 0,表示拥有相应的权限并且文件存在;否则返回-1,如果多个检查项组合在一起,只要其中任何一项不通过都会返回-1。

access()函数参数含义如下所示:

参数名称

参数含义

pathname

文件或目录的路径名

2

mode

是要检查的权限模式

mode参数可以取以下值之一:

取值

取值含义

F_OK:

检查文件或目录是否存在。

2

R_OK:

检查文件或目录是否可读。

3

W_OK:

检查文件或目录是否可写。

4

X_OK:

检查文件或目录是否可执行。

至此关于access()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过 access 函数检查文件是否存在,若存在、则继续检查执行进程的用户对该文件是否有读、写、执行权限。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo20_access.c文件,如下图所示:

vim demo20_access.c

 然后向该文件中添加以下内容,

#include <unistd.h>   
#include <stdio.h>   
#include <stdlib.h>   

int main(int argc,char *argv[])
{
    int ret;  // 声明一个用来存储函数返回值的变量
    ret = access("./test", F_OK);  // 调用 access 函数检查文件是否存在,并将结果存储到 ret 变量中
    if (-1 == ret)  // 判断文件是否存在
    {
        printf("file does not exist.\n");  // 如果文件不存在,输出相应的信息
        return -1;  // 并返回 -1
    }
    else
        printf("file exist\n");  // 如果文件存在,输出相应的信息
    ret = access("./test", R_OK);  // 检查文件是否具有读权限
    if (!ret)
        printf("是否有读权限: 有\n");
    else
        printf("是否有读权限: 无\n");
    ret = access("./test", W_OK);  // 检查文件是否具有写权限
    if (!ret)
        printf("是否有写权限: 有\n");
    else
        printf("是否有写权限: 无\n");
    ret = access("./test", X_OK);  // 检查文件是否具有执行权限
    if (!ret)
        printf("是否有执行权限: 有\n");
    else
        printf("是否有执行权限: 无\n");
    return 0;  // 返回 0,表示程序正常结束
}

第8行、第17行、第22行、第27行,分别调用了acces()函数,第一个参数为要检查属性的文件名,第二个属性为要检查的属性值,根据返回值来进行属性的判断。

保存退出之后,使用以下命令对demo20_access.c进行编译,编译完成如下图所示:

gcc -o demo20_access demo20_access.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 然后使用命令“ls -l”来查看文件属性,如下图所示:

从上图可以看到文件的读写权限为可读可写不具备执行权限,然后使用命令“./demo20_access”来运行,运行成功如下图所示:

可以看到程序运行成功之后,会打印对应的权限信息。

4.7修改文件权限

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\21”目录下,如下图所示:

 

学习前的疑问:

1.修改文件权限要使用哪个系统调用呢?

2.chmod()函数要怎样进行使用?

chmod()函数用来对文件权限进行修改,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode);

成功返回 0;失败返回-1,并设置 errno。

chmod()函数参数含义如下所示:

参数名称

参数含义

pathname

需要进行权限修改的文件路径,若该参数所指为符号链接,实际改变权限的文件是符号链接所指向的文件,而不是符号链接文件本身

2

mode

权限掩码,对不同用户和组设置可执行,读,写权限,使用八进制数表示

至此关于chmod()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过标准IO创建一个可以读写名为test的文件,并使用chmod()函数修改其权限为777。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo21_chmod.c文件,如下图所示:

vim demo21_chmod.c 

然后向该文件中添加以下内容, 

#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
    int ret;
    ret = chmod("./test", 0777);    // 将指定文件的权限设置为 0777,即读、写、执行权限都为最高

    if (ret == -1)    // 如果修改权限失败,则输出错误信息并返回 -1,表示程序异常终止
    {
        perror("chmod error");
        return -1;
    }

    return 0;    // 修改权限成功,返回 0,表示程序正常结束
}

需要注意的地方只有第7行,调用了chmod()函数,对test文件进行权限的修改,修改权限为777。

保存退出之后,使用以下命令对demo21_chmod.c进行编译,编译完成如下图所示:

gcc -o demo21_chmod demo21_chmod.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 然后使用命令“ls -l”来查看文件属性,如下图所示:

然后使用命令“./demo21_chmod”来运行,运行成功如下图所示:

可以看到程序运行成功之后,test文件的权限已经被修改为了777。

4.8软链接与硬链接

软链接(Symbolic Link)和硬链接(Hard Link)都是用于在文件系统中创建一个文件或目录的方法。它们的作用是使多个文件或目录共享同一块数据,从而节省磁盘空间和提高效率。但是,它们的实现方式不同,因此它们的特点和用法也有所不同。

软链接

软链接是一种特殊的文件类型,它是一个指向另一个文件或目录的快捷方式。软链接文件本身并不包含任何实际的数据,而是指向另一个文件或目录的路径。软链接可以跨越文件系统边界,并且可以指向不存在的文件或目录。

软链接的创建方式是使用ln命令,并使用参数-s来指定创建软链接。例如,下面的命令创建了一个名为"link_to_file"的软链接,它指向名为"file.txt"的文件:

ln -s file.txt link_to_file

软链接的特点:

1)软链接文件本身并不包含任何实际的数据,只是一个指向其他文件或目录的路径。

2)软链接可以跨越文件系统边界,因此可以指向另一个文件系统中的文件或目录。

3)软链接可以指向不存在的文件或目录。

4)软链接的权限和所有权都由其指向的文件或目录决定。

硬链接

硬链接是一种通过文件系统中的索引节点(Inode)来创建的链接。硬链接的本质是在文件系统中为同一文件或目录创建多个名称,它们共享同一块数据。硬链接只能在同一文件系统中创建,并且不能指向目录。

硬链接的创建方式是使用ln命令,并不使用-s参数。例如,下面的命令创建了一个名为"link_to_file"的硬链接,它指向名为"file.txt"的文件:

ln file.txt link_to_file

硬链接的特点:

1)硬链接创建的是同一个文件或目录的多个名称,它们共享同一块数据。

2)硬链接只能在同一文件系统中创建,因为不同的文件系统使用不同的索引节点。

3)硬链接不能指向目录。

删除硬链接不会影响其指向的文件或目录,只有当所有硬链接和原文件或目录都被删除后,才会真正释放磁盘空间。

至此,对于软链接和硬链接的介绍就完成了,那如何在系统编程中对软链接和硬链接进行创建呢,下面让我们一起进入本章节的学习吧。

4.8.1 创建硬链接 

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\22”目录下,如下图所示:

学习前的疑问:

1.硬链接的创建要使用哪个系统调用呢?

2.link()函数要怎样进行使用?

link()函数用来对硬链接进行创建,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <unistd.h>

int link(const char *oldpath, const char *newpath);

函数调用成功返回 0;失败将返回-1,并且会设置 errno。

link()函数参数含义如下所示:

参数名称

参数含义

oldpath

用于指定被链接的源文件路径

2

newpath

用于指定硬链接文件路径,如果newpath指定的文件路径已存在,则会产生错误

 至此关于link()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过 link函数创建test函数的硬链接hard。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo22_link.c文件,如下图所示:

vim demo22_link.c

然后向该文件中添加以下内容,: 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
	int ret;
	ret = link("./test", "./hard");	// 创建一个硬链接,将 test 文件的链接名设置为 hard

	if (ret == -1) 	// 如果创建链接失败,则输出错误信息并返回 -1,表示程序异常终止
	{
		perror("link error");
		return -1;
	}

	return 0;	// 创建链接成功,返回 0,表示程序正常结束
}

在第8行使用了link()函数,第一个参数为源文件名称,第二个参数为我们要创建的硬链接文件名称为hard。

保存退出之后,使用以下命令对demo22_link.c进行编译,编译完成如下图所示:

gcc -o demo22_link demo22_link.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 保存退出之后,使用命令“./demo22_link”来运行,创建test文件的硬连接文件hard,运行成功如下图所示:

可以看到hard文件也被成功创建了,且test和hard的inode号相同,证明我们的硬链接创建成功了。

4.8.2 创建软链接 

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\23”目录下,如下图所示:

学习前的疑问:

1.软链接的创建要使用哪个系统调用呢?

2.symlink()函数要怎样进行使用?

symlink()用来创建软链接,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <unistd.h>

int symlink(const char *target, const char *linkpath);

调用成功时返回 0;失败将返回-1,并会设置 errno。

symlink()函数参数含义如下所示:

参数名称

参数含义

target

软链接指向的目标文件或目录的路径

2

linkpath

新创建的软链接的路径。

 至此关于fread()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过symlink()函数创建test文件的软链接soft。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo23_symlink.c文件,如下图所示:

vim demo23_symlink.c

然后向该文件中添加以下内容, 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int ret;
    ret = symlink("./test", "./soft");    // 创建一个软链接,将 test 文件的链接名设置为 soft
    
	if (ret == -1)     // 如果创建链接失败,则输出错误信息并返回 -1,表示程序异常终止
    {
        perror("link error\n");
        return -1;
    }

    return 0;    // 创建链接成功,返回 0,表示程序正常结束
}

保存退出之后,使用以下命令对demo23_symlink.c进行编译,编译完成如下图所示:

gcc -o demo23_symlink demo23_symlink.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 然后使用命令“./demo23_symlink”来运行创建test的软链接,运行成功如下图所示:

可以看到程序运行成功之后,soft文件被成功创建,使用“ls -l”查看文件属性,可以看到sotf文件是test文件的软链接。

4.8.3 读取软链接文件路径

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\24”目录下,如下图所示:

学习前的疑问:

1.读取软链接文件路径要使用哪个系统调用呢?

2.readlink()函数要怎样进行使用?

readlink()函数用来对软链接的源文件路径进行读取,所使用的头文件和函数原型,如下图所示:

所需头文件

函数原型

1

#include <unistd.h>

ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

函数调用成功之后将返回读取到的字节数。失败将返回-1,并会设置 errno。

readlink()函数参数含义如下所示:

参数名称

参数含义

pathname

需要读取的软链接文件路径。只能是软链接文件路径,不能是其它类型文件,否则调用函数将报错。

2

buf

用于存放路径信息的缓冲区。

3

bufsiz

读取大小,一般读取的大小需要大于链接文件数据块中存储的文件路径信息字节大小。

至此关于readlink()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过readlink()函数读取软链接源文件的路径并打印。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo24_readlink.c文件,如下图所示:

vim demo24_readlink.c

然后向该文件中添加以下内容: 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    char buf[50];  // 用于存储读取到的软链接文件内容
    int ret;
    ret = readlink("./soft", buf, sizeof(buf)); //读取软链接文件 "./soft" 的内容,存储到 buf 中
if (ret == -1)  // 如果读取失败,输出错误信息并返回 -1
{
    perror("readlink error");
    return -1;
}
printf("%s\n", buf);  // 打印读取到的软链接文件内容
return 0;
}

保存退出之后,使用以下命令对demo24_readlink.c进行编译,编译完成如下图所示:

gcc -o demo24_readlink demo24_readlink.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 保存退出之后,使用以下命令来创建test文件的软链接文件soft,创建成功如下图所示:

ln -s test soft

然后使用命令“./demo24_readlink”来运行该程序,运行成功如下图所示: 

可以看到程序运行成功之后,会打印soft软链接文件的本身文件test。

4.9文件删除

4.9.1 删除文件(系统调用)

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\25”目录下,如下图所示:

学习前的疑问:

1.文件删除要使用哪个系统调用呢?

2.unlink()函数要怎样进行使用?

unlink()函数用于删除指定的文件或目录,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <unistd.h>

int unlink(const char *pathname);

函数调用成功时返回 0;失败将返回-1,并设置 errno。

unlink()函数的参数含义如下所示:

参数名称

参数含义

pathname

要删除的文件或目录的路径

 至此关于fread()函数的相关`讲解就完成了,下面进行相应的实验。

函数功能:

unlink()系统调用,用于移除/删除一个硬链接(从其父级目录下删除该目录条目)。

头文件和函数原型:

#include <unistd.h>

int unlink(const char *pathname);

参数含义:

pathname:需要删除的文件路径,可使用相对路径、也可使用绝对路径,如果 pathname 参数指定的文件不存在,则调用 unlink()失败

返回值

成功返回 0;失败将返回-1,并设置 errno。

实验要求:

通过unlink()函数删除test硬链接文件。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo25_unlink.c文件,如下图所示:

vim demo25_unlink.c

然后向该文件中添加以下内容,、 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

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

    ret = unlink("./test");    // 使用unlink函数删除指定的文件
    if (ret == -1)
    {
        perror("unlink error");
        return -1;
    }
    return 0;
}

保存退出之后,使用以下命令对demo25_unlink.c进行编译,编译完成如下图所示:

gcc -o demo25_unlink demo25_unlink.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 保存退出之后,使用命令“./demo25_unlink”来运行该程序,运行成功如下图所示:

程序运行成功之后,会发现test文件被删除了,至此,关于unlink函数的实验就完成了。

4.9.2 删除文件(C库函数) 

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\26”目录下,如下图所示:

学习前的疑问:

  1. remove()函数要怎样进行使用?
  2. 为什么要学习remove()函数

remove函数与unlink函数类似,用于删除指定的文件。不同之处在于,remove函数可以删除指定路径下的任意类型的文件,包括普通文件、目录等。如果要删除非空目录,remove函数会自动递归删除其下的所有文件和子目录。

remove函数所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <stdio.h>

int remove(const char *pathname);

调用成功时成功返回 0,失败将返回-1,并设置 errno。

remove()函数参数含义如下所示:

参数名称

参数含义

pathname

要删除的文件或目录的路径

需要注意的是,与unlink函数类似,删除文件操作也是不可逆的,因此在使用remove函数时,应该谨慎处理,避免误删重要文件。如果需要保留备份或是恢复删除的文件,可以在删除文件之前先备份文件。另外,需要注意的是,删除文件操作需要有足够的权限,否则会删除失败。

至此关于remove()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

本代码所要实现的目标为通过remove()函数删除test文件。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo26_remove.c文件,如下图所示:

vim demo26_remove.c

然后向该文件中添加以下内容 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int ret; // 存储函数调用结果的变量
    ret = remove("./test"); // 调用 remove 函数删除名为 "test" 的文件
    if (ret == -1) // 如果返回值为 -1,说明删除文件失败
    {
        perror("remove error"); // 输出错误信息
        return -1; // 返回错误代码
    }
    return 0; // 删除成功,返回 0
}

保存退出之后,使用以下命令 对demo26_remove.c进行编译,编译完成如下图所示:

gcc -o demo26_remove demo26_remove.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

保存退出之后,使用命令“./demo26_remove”来运行该程序,运行成功如下图所示: 

程序运行成功之后,会发现test文件被删除了。

4.10文件重命名

本小节代码在配套资料“iTOP-3588开发板\03_【iTOP-RK3588开发板】指南教程\03_系统编程配套程序\27”目录下,如下图所示:

学习前的疑问:

1.文件重命名要使用哪个C语言库函数?

2.rename()函数要怎样进行使用?

在系统编程中使用rename()函数对文件进行重命名,所使用的头文件和函数原型,如下所示:

所需头文件

函数原型

1

#include <stdio.h>

int rename(const char *oldpath, const char *newpath);

 函数调用成功返回 0,失败将返回-1,并设置 errno。

rename()函数参数含义如下所示:

参数名称

参数含义

oldpath

原文件路径

2

newpath

新文件路径

至此关于rename()函数的相关讲解就完成了,下面进行相应的实验。

实验要求:

通过rename()函数将test文件名修改为new_file。

实验步骤:

首先进入到ubuntu的终端界面输入以下命令来创建demo27_rename.c文件,如下图所示:

vim demo27_rename.c

然后向该文件中添加以下内容: 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{

    int ret;    // 定义一个变量 ret 来存储操作结果
    ret = rename("./test", "./new_file");    // 调用 rename 函数,将文件名为“test”的文件重命名为“new_file”

    if (ret == -1)    // 如果重命名失败,输出错误信息并返回 -1
    {
        perror("rename error");
        return -1;
    }

    return 0;    // 重命名成功,返回 0
}

保存退出之后,使用以下命令对demo27_rename.c进行编译,编译完成如下图所示:

gcc -o demo27_rename demo27_rename.c

然后使用命令“vim test”创建test文件,并添加以下内容:

hello world!!

添加完成如下图所示:

 保存退出之后,使用命令“./demo27_rename”来运行该程序,运行成功如下图所示:

程序运行成功之后,会发现test文件已经更名为了new_file。至此关于rename()函数的实验就完成了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/545746.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[MySQL]数据库原理8——喵喵期末不挂科

希望你开心&#xff0c;希望你健康&#xff0c;希望你幸福&#xff0c;希望你点赞&#xff01; 最后的最后&#xff0c;关注喵&#xff0c;关注喵&#xff0c;关注喵&#xff0c;大大会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的…

构建鸿蒙ACE静态库

搭建开发环境 根据说明文档下载鸿蒙全部代码&#xff0c;一般采取第四种方式获取最新代码(请保证代码为最新) 源码获取Windows下载编译环境 MinGW GCC 7.3.0版本 请添加环境变量IDE 可以使用两种 CLion和Qt,CLion不带有环境需要安装MinGW才可以开发,Qt自带MinGW环境&#xff0…

Itasca pfc3d/3dec/flac3d/massflow 9.0 授权

所有 Itasca 软件都建立在每个程序基础的共同元素层之上——无论程序使用何种数值方法或元素。因此&#xff0c;无论是使用 DEM 软件&#xff08;如 3DEC 或 PFC&#xff09;&#xff0c;还是使用 FLAC3D 等连续体软件&#xff0c;都会有许多流程、实用程序和功能是所有这些软件…

靠Python实现经济自由,学会了你也可以

不知道大家有没有注意到&#xff0c;最近关注的很多人都在聊“副业and兼职”这件事。 毕竟单一收入已经不能满足现代人的需求了。 对于普通人来说&#xff0c;想要跳出固定思维和舒适圈&#xff0c;相比于孤注一掷的创业&#xff0c;更推荐兼职。 很多人想要创业&#xff0c;…

【Qt】:对话框(二)

对话框 一.消息对话框&#xff08;QMessageBox&#xff09;1.自己构建2.使用静态函数构建 二.颜色对话框&#xff08;QDialog&#xff09;三.文件对话框&#xff08;QFileDialog&#xff09;四.字体对话框&#xff08;QFontDialog&#xff09;五.输入对话框&#xff08;QInputD…

JMM(Java Memory Model java内存模型

目标&#xff1a; 搞清楚高并发场景下&#xff0c;java内存模型是怎么支持的&#xff0c;对象在内存中是怎么布局的&#xff1f; 目录 目标&#xff1a; 搞清楚高并发场景下&#xff0c;java内存模型是怎么支持的&#xff0c;对象在内存中是怎么布局的&#xff1f; 1.硬件层…

华火电焰灶全国经销商加盟_优势怎么样_费用多少_华焰天下

随着科技的不断进步&#xff0c;电焰灶作为现代厨房的重要设备&#xff0c;其市场需求持续增长。华火电焰灶&#xff0c;凭借其独特的技术优势和广泛的市场前景&#xff0c;吸引了众多投资者的目光。本文将从华火电焰灶的优势、加盟费用以及华焰天下的机遇三个方面&#xff0c;…

配置IP地址并验证连通性

1.实验环境 主机 A和主机 B通过一根网线相连&#xff0c;如图6.13所示。 图6.13 实验案例一示意图 2.需求描述 为两台主机配置!P地址&#xff0c;验证P地址是否生效&#xff1b;验证同一网段的两台主机可以互通&#xff0c;不同网段的主机不能直接互通。 3.推荐步骤 为两台…

第四百五十四回

文章目录 1. 问题描述2. 优化方法2.1 缩小范围2.2 替代方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何获取AppBar的高度"相关的内容&#xff0c;本章回中将介绍关于MediaQuery的优化.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 问题描述 我们在…

自己开发的App如何上架,详细解读App上架操作流程

对于企业或个人开发的App&#xff0c;上架是必经之路。然而&#xff0c;许多人不清楚如何进行App上架。工信部在2023年规定&#xff0c;App必须备案才能上架。那么&#xff0c;让我们一起了解App上架流程吧。 1. 准备上架所需材料 在上架App之前&#xff0c;需要准备应用图标…

【学习笔记十三】EWM常见上架策略介绍

一、手工维护上架策略 系统不确定Storage type 和 bin&#xff0c;需要在创建仓库任务时或者确认仓库任务时手工输入仓位 1.后台配置-定义存储类型的类型0010 ①存储行为&#xff1a;标准仓位 ②入库规则&#xff1a;空仓未或添加至现有库存/空仓位 ③通用仓库任务&#x…

【学习笔记十二】EWM上架仓位确定逻辑及操作演示

一、前言 关于EWM上架仓位确定的过程&#xff0c;我在【学习笔记十一】EWM上架目标仓位确定过程及配置-CSDN博客中讲到了 EWM根据仓库类型&#xff08;storage type&#xff09;、仓库分区&#xff08;storage section&#xff09;和上架策略&#xff08;putaway strategies&…

绿色地狱steam叫什么 绿色地狱steam怎么搜

绿色地狱steam叫什么 绿色地狱steam怎么搜 《绿色地狱》是一款以亚马逊雨林为背景的开放世界生存模拟游戏。玩家们扮演一名被困在丛林中的冒险者&#xff0c;玩家在游戏内需要学习采集资源、建造庇护所、狩猎和烹饪食物&#xff0c;同时要面对丛林中的危险和挑战&#xff0c;…

Oracle 19c补丁升级(Windows)

文章目录 一、打补丁前备份检查1、补丁包获取2、备份数据包以及数据库软件3、检查OPatch版本 二、补丁升级1、更新OPatch2、关闭监听以及服务3、补丁升级过程4、启动监听以及服务 三、数据库补丁应用 一、打补丁前备份检查 1、补丁包获取 补丁包&#xff1a; 百度网盘链接&am…

Neo4j 图形数据库中有哪些构建块?

Neo4j 图形数据库具有以下构建块 - 节点属性关系标签数据浏览器 节点 节点是 Graph 的基本单位。 它包含具有键值对的属性&#xff0c;如下图所示。 NEmployee 节点 在这里&#xff0c;节点 Name "Employee" &#xff0c;它包含一组属性作为键值对。 属性 属性是…

李廉洋;4.12现货黄金,美原油最新走势分析及策略。

现货黄金在美盘末将历史新高刷至2377美元/盎司。美国3月份PPI指数较上年同期上升2.1%&#xff0c;为11个月来的最高增幅&#xff0c;这份数据加之此前火爆的CPI指数&#xff0c;为美联储实现2%目标所面临的坎坷之路奠定了基础。不过&#xff0c;PPI报告中的细节让担心通胀再度加…

@Transactional使用中的三类坑

我们知道事务有声明式事务和编程式事务两种&#xff0c;编程式事务代码侵入较高&#xff0c;声明式事务侵入较低&#xff0c;在项目中常有使用&#xff0c;然而&#xff0c;不正确的使用声明式事务&#xff0c;可能让代码未能按照我们的预期执行。 一、事务可能没有生效 Tran…

OpenHarmony开发案例:【电影卡片】

介绍 本篇Codelab基于元服务卡片的能力&#xff0c;实现带有卡片的电影应用&#xff0c;介绍卡片的开发过程和生命周期实现。需要完成以下功能&#xff1a; 元服务卡片&#xff0c;用于在桌面上添加2x2或2x4规格元服务卡片。关系型数据库&#xff0c;用于创建、查询、添加、删…

前端知识学习笔记-五(ECMAScript 6)

命令行工具 在正式讲解ES6新特性之前&#xff0c;我们需要了解一些命令行工具&#xff0c;在日后的课程中&#xff0c;我们会经常用到命令行 常用命令行工具有两种 CMD 命令行工具 PowerShe门命令行工具 CMD命令行 打开命令行窗口 win: 左下角开始&#xff0c;找到运行&#…

IntelliJ IDEA(WebStorm、PyCharm、DataGrip等)设置中英文等宽字体,英文为中文的一半(包括标点符号)

1.设置前&#xff08;idea默认字体为 JetBrains Mono&#xff09; 2.设置后&#xff08;楷体&#xff09;