正点原子I.MX6U嵌入式Linux(正点原子I.MX6U嵌入式Linux)

今日头条/西瓜视频/抖音短视频 同名:正点原子原子哥

感谢各位的关注和支持,你们的支持是原子哥无限前进的动力。

第二章《文件I/O基础》

由于本章内容较多,所以第二章《文件I/O基础》将会分为几个部分进行内容的发布,更多精彩原创文章请持续关注正点原子原子哥官方账号。

点击打开testApp_1.c文本编辑页面,接下来就可以在testApp_1.c源文件中编写第一个实战例子对应的源代码了,以下是笔者给大家提供的一份示例代码,大家可以进行参考,但还是希望大家能够根据本章所学知识独立完成代码编写:

示例代码 2.8.1 编程实战例子1

/*************************************************************** Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved. 文件名 : testApp_1.c 作者 : 邓涛 版本 : V1.0 描述 : 论坛 : www.openedv.com 日志 : 初版V1.0 2021/01/05 创建 ***************************************************************/ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main(void) { char buffer[1024]; int fd1, fd2; int ret; /* 打开src_file文件 */ fd1 = open("./src_file", O_RDONLY); if (-1 == fd1) { printf("Error: open src_file failed!\n"); return -1; } /* 新建dest_file文件并打开 */ fd2 = open("./dest_file", O_WRONLY | O_CREAT | O_EXCL, S_IRWXU | S_IRGRP | S_IROTH); if (-1 == fd2) { printf("Error: open dest_file failed!\n"); ret = -1; goto err1; } /* 将src_file文件读写位置移动到偏移文件头500个字节处 */ ret = lseek(fd1, 500, SEEK_SET); if (-1 == ret) goto err2; /* 读取src_file文件数据,大小1KByte */ ret = read(fd1, buffer, sizeof(buffer)); if (-1 == ret) { printf("Error: read src_file filed!\n"); goto err2; } /* 将dest_file文件读写位置移动到文件头 */ ret = lseek(fd2, 0, SEEK_SET); if (-1 == ret) goto err2; /* 将buffer中的数据写入dest_file文件,大小1KByte */ ret = write(fd2, buffer, sizeof(buffer)); if (-1 == ret) { printf("Error: write dest_file failed!\n"); goto err2; } printf("OK: test successful\n"); ret = 0; err2: close(fd2); err1: close(fd1); return ret; }

此代码中用到了库函数printf,是一个格式化输出函数,用于将格式化打印信息输出显示到屏幕上(终端),使用此函数需要包含标准I/O库头文件<stdio.h>,对于有C语言编程经验的读者来说,如果对该函数的使用方法并不了解,可以查看4.8.1小节内容。

编译源码文件

代码编写完成之后,接下来我们需要对源代码进行编译,在vscode中点击上边菜单“终端--->新终端”打开一个终端,打开的终端将会在下面显示出来,如下所示:

正点原子I.MX6U嵌入式Linux(正点原子I.MX6U嵌入式Linux)(1)

图 2.8.6 在vscode中打开终端

vscode提供了终端功能,这样就可以不使用Ubuntu自带的终端了,非常的方便、不需要在Ubuntu终端和vscode软件之间进行切换,进入到1_chapter目录下,如下所示:

正点原子I.MX6U嵌入式Linux(正点原子I.MX6U嵌入式Linux)(2)

图 2.8.7 进入1_chapter目录

在该目录下我们直接使用Ubuntu系统提供的gcc编译器对源文件进行编译,编译生成一个可在Ubuntu系统下运行的可执行文件,执行如下命令:

gcc -o testApp_1 testApp_1.c

gcc是Ubuntu系统下所使用的C语言编译器,-o选项指定编译生成的可执行文件的名字,testApp_1.c表示需要进行编译的C语言源文件,gcc命令后面可以携带很多的编译相关的选项,这里不给大家介绍这个内容,这不是本文档我们需要去了解的重点,如果后面有机会可以给大家介绍下。编译完成之后会生成对应的可执行文件,如下所示:

正点原子I.MX6U嵌入式Linux(正点原子I.MX6U嵌入式Linux)(3)

图 2.8.8 编译源文件

运行可执行文件测试

编译完成之后,接下来可以运行测试了,首先我们先准备一个文件src_file,这个是例子要求需要打开一个已经存在的文件,文件大小大于或等于1Kbyte,这里笔者已经将src_file文件放置到1_chapter目录下了,如下所示:

正点原子I.MX6U嵌入式Linux(正点原子I.MX6U嵌入式Linux)(4)

图 2.8.9 准备好一个测试需要用到的文件

直接在当前目录下运行testApp_1可执行文件:

正点原子I.MX6U嵌入式Linux(正点原子I.MX6U嵌入式Linux)(5)

图 2.8.10 运行testApp_1可执行文件

运行成功之后会生成dest_file文件,这就是testApp_1.c源码中使用open创建的新文件,通过查看它的权限可知与源码中设置的权限是相同的,文件大小为1Kbyte,其中这1Kbyte字节数据是从src_file文件中读取过来的。

剩下的几个例子希望大家自己独立完成。

Tips:最后再给大家说一点,就是关于函数返回值的问题,我们可以发现,本章给大家所介绍的这些函数都是有返回值的,其实不管是Linux应用编程API函数,还是驱动开发中所使用到的函数,基本上都是有返回值的,返回值的作用就是告诉开发人员此函数执行的一个状态是怎样的,执行成功了还是失败了,在Linux系统下,绝大部分的函数都是返回0作为函数调用成功的标识、而返回负数(譬如-1)表示函数调用失败,如果大家学习过驱动开发,想必对此并不陌生,所以很多时候可以使用如下的方式来判断函数执行成功还是失败:

if (func()) { //执行失败 } else { //执行成功 }

当然以上说的是大部分情况,并不是所有函数都是这样设计,所以呢,这里笔者也给大家一个建议,自己在进行编程开发的时候,自定义函数也可以使用这样的一种方法来设计你的函数返回值,不管是裸机程序亦或是Linux应用程序、驱动程序。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页