700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 4. linux调用文件计算阶乘前5项和_嵌入式Linux系统编程——文件读写访问 属性 描述符 API

4. linux调用文件计算阶乘前5项和_嵌入式Linux系统编程——文件读写访问 属性 描述符 API

时间:2024-04-06 11:32:32

相关推荐

4. linux调用文件计算阶乘前5项和_嵌入式Linux系统编程——文件读写访问 属性 描述符 API

Linux 的文件模型是从 Unix 的继承而来,所以 Linux 继承了 UNIX 本身的大部分特性,然后加以扩展,本章从 UNIX 系统接口来描述 Linux 系统结构的特性。

操作系统是通过一系列的系统调用来提供服务的,系统调用可以简单的定义为可以被用户程序调用的

操作系统内的函数。一般说来,我们可以借助于系统调用来获得更高的效率,或者访问标准库中没有的某些功能。

本文主要从以下几个方面讲述嵌入式Linux系统编程文件相关的内容

1 文件与文件访问基本概念

2 Linux 文件

3 理解文件描述符

4 文件访问基本概念

5 文件访问的系统调用 API

6 文件的创建、打开和关闭

7 文件读写

8 文件的随机存取

9 文件的访问权限

10 修改文件属性

11 其他常用的 API

12 实例: fopen 和 getc 函数的实现

2.1 文件与文件访问基本概念

2.1.1 Linux 文件

对普通计算机用户来说,文件是存储在永久性存储器上的一段数据流,通常是可执行程序或者是某种

格式的数据。文件放置于文件夹,文件夹放置于某个磁盘分区中。这是从普通计算机用户眼里看到的文件。 但 Linux 操作系统中文件的概念,却远远不局限与此,文件是 Linux 对大多数系统资源访问的接口。

Linux 常见的文件类型:普通文件、目录文件、设备文件、管道文件、套接字和链接文件等等。

(1)普通文件(regular file),而前面提到的普通计算机用户看到的文件,仅仅是 Linux 文件类型中的一种,我们称之为普通文件,它们通常驻留在磁盘上的某处。普通文件按照信息存储方式来划分,可分为

文本文件和二进制文件:

文本文件:这类文件以文本的某种编码(比如 ASCII 码)形式存储在存储器中。它是以“行”为基本结构的一种信息组织和存储方式。

二进制文件:这类文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们,只有通过

相应的软件才能将其显示出来。二进制文件一般是可执行程序、图形、图像、声音等等。

例如用 ls 命令查看一个普通文件:

符号链接文件的属性“lrwxrwxrwx”的第一个字母是“l”。

上述是 Linux 丰富的文件类型,包括除了普通文件和目录文件之外的几种“特殊文件”,正是由于这些“特殊文件”的存在,Linux 程序员可以按照统一的接口来实现基本文件读写、设备访问、硬盘读写、网络通信、系统终端,甚至内核状态信息的访问等等。无论是哪种类型的文件,Linux 都把他们看作是无结构的流式文件,把文件的内容看作是一系列有序的字符流。

在 Linux 操作系统中,和文件操作相关的最基本元素是:目录结构、索引节点和文件的数据本身。

(1)目录结构。系统中的每一个目录都处于一定的目录结构当中。目录结构含有目录中所有目录的列表,每个目录项都含有一个文件名称和一个索引节点。借助于名称,应用程序可以访问目录项的内容,而索引节点提供了文件自身的信息。所以,目录只是将文件的名称和它的索引节点号结合在一起的一张表,目录中每一对文件名称和索引节点号称为一个连接。对于一个文件来说有唯一的索引节点号与之对应,对于一个索引节点号,却可以有多个文件名与之对应。因此,在磁盘上的同一个文件可以通过不同的路径去访问它。

(2)索引节点。目录结构包含文件名称和目录位置等信息,而索引节点本身并不包含这些信息,因为Linux 允许使用多个文件名来引用磁盘上的同一块数据,多个文件名都可以访问同一个索引节点。索引节点包含了一个文件的访问权限、文件大小、文件最后更改的时间、文件的所有者和文件相关的特殊标志以及其他细节。

(3)文件的数据,它的存储位置由索引节点指定。有些特殊文件,比如管道及设备文件,在硬盘上不具

有数据区域。而普通文件和目录都拥有数据区域。

后面我们将了解如何获取目录结构信息、从索引节点获取文件信息以及访问文件的数据。

2.1.2 理解文件描述符

在 UNIX 类操作系统中,所有的外围设备(包括键盘和显示器)都被看作是文件系统中的文件,因此,

所有的输入/输出都要通过读文件或写文件完成。也就是说,通过一个单一的接口就可以处理外围设备和程序之间的所有通信。

通常情况下,在读或写文件之前,必须先将这个意图通知系统,该过程称为打开文件。如果是写一个

文件,则可能需要先创建该文件,也可能需要丢弃该文件中原先已存在的内容。系统检查你的权力(该文件是否存在?是否有访问它的权限?),如果一切正常,操作系统将向程序返回一个小的非负整数,该整数称为文件描述符。任何时候对文件的输入/输出都是通过文件描述符标识文件。(文件描述符类似于标准库中的文件指针或 MS-DOS 中的文件句柄。)系统负责维护已打开文件的所有信息,用户程序只能通过文件描述符引用文件。

因为大多数的输入/输出是通过键盘和显示器来实现的,为了方便起见,UNIX 对此做了特别的安排。

当命令解释程序(即“shell”)运行一个程序的时候,它将打开 3 个文件,对应的文件描述符分别为 0、1、 2,依次表示标准输入、标准输出和标准错误。如果程序从文件 0 中读,对 1 和 2 进行写,就可以进行输入/输出而不必关心打开文件的问题。

程序的使用者可通过“”重定向程序的 I/O:

program outfile

这种情况下,shell 把文件描述符 0 和 1 的默认值改为指定的文件。通常文件描述符 2 仍与显示器相

关联,这样,出错信息会输出到显示器上。与管道相关的输入/输出也有类似的特性。在任何情况下,文件赋值的改变都不是由程序完成的,而是由 shell 完成的。只要程序使用文件 0 作为输入,文件 1 和 2作为输出,它就不会知道程序的输入从哪里来,并输出到哪里去。

2.1.3 文件访问基本概念

上一节我们提到和文件操作相关的最些本元素:目录结构、索引节点和文件数据。通过 opendir()及

相关函数,可以获取目录结构信息。通过系统调用 stat()可以从索引节点获得文件信息。通过常用的文件操作 open()、read()等等可以访问文件的数据。Linux 提供了丰富的文件访问接口,首先,我们需要了解Linux 文件访问的实质,然后,才能灵活运用各种文件访问函数以及系统调用进行文件操作。

在 Linux 操作系统中,每一个文件都有一个唯一的索引节点,而每个索引节点可以有一个或者多个指

向它的符号名,这些符号名就是文件的路径名。一个文件路径名只能指向一个索引节点(但一个索引节点可以有多个路径名),因此文件路径名唯一的标识单个文件。比如“/home/alex/myfile.txt”是一个文件路

径名,指向的是“/home/alex”目录下的 myfile.txt 文件,通过“/home/alex/myfile.txt”这个路径名只能访问到这个文件。

程序要访问一个文件,首先需要通过一个文件路径名打开文件。当进程打开一个文件的时候,进程将

获得一个非负整数标识,即“文件描述符”。通过文件描述符,可以对文件进行 I/O 处理。

在 Linux 操作系统中各种类型的文件都采用统一的 I/0 方法来进行访问。因此,从磁盘中读取一个文

件中的程序和从网络中读取数据的程序一样简单,而且,程序员可以使用统一接口来访问硬件设备和系统端口等等。

对文件执行 I/0 操作,有两种基本方式:一种是系统调用的 I/0 方法,另一种是基于流的 I/O 方法。

系统调用的 I/O 方法提供了最基本的文件访问接口,包括 open()、close()、write()、read()和 lseek()

等。基于流的 I/0 方法实际上是建立在系统调用的 I/0 方法基础上的 C 函数库,它基于系统调用方法的封装并增加了额外的功能,例如采用缓冲技术来提高程序的效率、输入解析以及格式化输出等。然而在处理设备、管道、网络套接字和其他特殊类型的文件的时候,必须使用系统调用 I/0 方法。

系统调用 I/0 方法和基于流的 I/0 方法的区别是:

(1)基于流的文件操作函数的名字都是以字母“f”开头,而系统调用函数则不同。例如流函数 fopen()

对应于系统调用的 open()。

(2)系统调用 I/0 方法是更低一级的接口,通常完成相同的任务是,比使用基于流的 I/0 方法需要更多

编码的工作量。

(3)系统调用直接处理文件描述符,而流函数则处理“FILE*”类型的文件句柄。

(4)基于流的 I/0 方法是对系统调用方法的封装,流 I/0 方法使用自动缓冲技术,使程序能减少系统调

用,从而提高程序的性能。

(5)基于流的 I/0 方法可以支持格式化输出,比如使用 fprintf()这样的函数。

(6)基于流的 I/0 方法替用户处理有关系统调用的细节,比如系统调用被信号中断的处理等等。

基于流的 I/0 方法显然给程序员提供了极大的方便,但是某些程序却不能使用基于流的 I/0 方法。比

如使用缓冲技术使得网络通信陷入困境,因为它将干扰网络通讯所使用的通信协议。考虑到这两种 I/O 方法的不同,在使用终端或者通过文件交换信息是,通常采用基于流的 I/O 方法。而使用网络或者管道通信时,通常采用系统调用的 I/O 方法。

源文件:read_test.c

#include #include #include int main( int argc, char **argv ) {int fd_read;char buf[100];int ret;/*判断是否传入文件名*/if( argc < 2 ){printf("Usage: read_test FILENAME");return -1;}/*打开要读取的文件*/fd_read = open( argv[1], O_RDONLY );if( fd_read == -1 ){perror( "open error" );return -1;}/*读取数据*/ret = read( fd_read, buf, sizeof( buf ) );printf("read return = [%d]", ret );/*如果读出数据,则打印数据*/if( ret >= 0 ){printf("=========== buf ===========");printf("%s", buf );printf("===========================");}else{perror( "read error" );}close( fd_read );return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。