首页 理论教育 Linux系统编程:文件编程实验

Linux系统编程:文件编程实验

时间:2023-11-18 理论教育 版权反馈
【摘要】:此时再使用read函数作用于这个文件会导致read返回0。

Linux系统编程:文件编程实验

●实验目的:

学会创建文件,并制定文件访问属性;

学会使用C库函数和Linux系统调用,并理解它们的区别。

●实验要求:

编写应用程序,创建一可读可写的文件;

使用库函数,实现文件copy功能。

●实验器材:

软件:安装了Linux的vmware虚拟机

硬件:PC机一台。

●实验步骤:

(1)文件创建。

①编写实验代码file_creat.c。

②编译应用程序file_creat.c。

用gcc命令编译file_create.c后生成可执行文件file_creat。

③运行应用程序。

运行该程序后,可以发现在当前目录下产生了test.txt文件。

④该实验学习如何用Linux的系统调用创建一个文件,并设置文件的访问属性,文件操作是Linux应用编程的基础。

(2)文件拷贝

①编写实验代码file_cp.c。

②编译应用程序file_cp.c。

③运行应用程序。

将file_cp.c拷贝为test.c,可以看到运行程序后文件夹出现了test.c,与file_cp.c大小和内容都一样。

④要注意区分用C库函数和Linux系统调用对文件操作的方法。比如C库函数fread就没有像Linux系统调用read函数那样返回成功读取了多少个字节,因此只有清楚它们之间的区别,才能熟练运用。

●上机报告要求:

编写一应用程序实现如下功能:使用open()函数创建一个名为file.txt,权限为666的文件,并向其中写入字符串“hello world”,然后使用read()函数把写入的内容读取出来并在终端上显示输出。

分别写出open()、read()、write()、close()函数的函数原型、功能、返回值、函数参数的意义。

(1)open()函数。

①功能描述:用于打开或创建文件,在打开或创建文件时可以指定文件的属性及用户的权限等参数。

所需头文件:#include <sys/types.h>,#include <sys/stat.h>,#include <fcntl.h>

②函数原型:int open(const char *pathname,int flags,int perms)

③参数:

pathname:被打开的文件名(可包括路径名,如“dev/ttyS0”)。

flags:文件打开方式,有以下几种:

O_RDONLY:以只读方式打开文件。

O_WRONLY:以只写方式打开文件。

O_RDWR:以读写方式打开文件。

O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三个参数为其设置权限。

O_EXCL:如果使用O_CREAT时文件存在,则返回错误消息。这一参数可测试文件是否存在。此时open是原子操作,可防止多个进程同时创建同一个文件。

O_NOCTTY:使用本参数时,若文件为终端,那么该终端不会成为调用open()的那个进程的控制终端。

O_TRUNC:若文件已经存在,就会删除文件中的全部原有数据,并且设置文件大小为0。

O_APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾,即将写入的数据添加到文件的末尾。(www.xing528.com)

O_NONBLOCK:如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式。

O_SYNC:使每次write都等到物理I/O操作完成。

O_RSYNC:read等待所有写入同一区域的写操作完成后再进行。

在open()函数中,flags参数可以通过“|”组合构成,但前3个标准常量(O_RDONLY,O_WRONLY和O_RDWR)不能互相组合。

perms:被打开文件的存取权限,可用两种方法表示,既可以用宏定义表示法,也可以用八进制表示法。其中用一组宏定义为:S_I(R/W/X)(USR/GRP/OTH),R/W/X分别表示读写执行权限,USR/GRP/OTH分别表示文件的所有者/文件所属组/其他用户。

例如,S_IRUSR|S_IWUSR 表示设置文件所有者的可读可写属性。八进制表示法中 600也表示同样的权限。

④返回值:

成功:返回文件描述符。

失败:返回-1。

(2)close()函数。

①功能描述:用于关闭一个被打开的文件。

所需头文件:#include <unistd.h>

②函数原型:int close(int fd)

③参数:fd文件描述符。

④函数返回值:0成功,-1出错。

(3)read()函数。

①功能描述:从文件读取数据。

所需头文件:#include <unistd.h>

②函数原型:ssize_t read(int fd, void *buf, size_t count)

③参数:

fd:将要读取数据的文件描述符。

buf:指缓冲区,即读取的数据会被放到这个缓冲区中去。

count:表示调用一次read操作,应该读多少数量的字符。

④返回值:返回所读取的字节数;0(读到EOF);-1(出错)。

以下几种情况会导致读取到的字节数小于 count:

A.读取普通文件时,读到文件末尾还不够count字节。例如:如果文件只有30字节,而我们想读取100字节,那么实际读到的只有30字节,read函数返回30。此时再使用read函数作用于这个文件会导致read返回0。

B.从终端设备(terminal device)读取时,一般情况下每次只能读取一行。

C.从网络读取时,网络缓存可能导致读取的字节数小于count字节。

D.读取pipe或者FIFO时,pipe或FIFO里的字节数可能小于count。

E.从面向记录(record-oriented)的设备读取时,某些面向记录的设备(如磁带)每次最多只能返回一个记录。

F.在读取了部分数据时被信号中断。读操作始于cfo。在成功返回之前,cfo增加,增量为实际读取到的字节数。

(4)write()函数。

①功能描述:向文件写入数据。

所需头文件:#include <unistd.h>

②函数原型:ssize_t write(int fd, void *buf, size_t count)

③参数:write函数向 filedes中写入count字节数据,数据来源为buf。返回值一般总是等于count,否则就出错了。常见的出错原因是磁盘空间满了或者超过了文件大小限制。

④返回值:写入文件的字节数(成功);-1(出错)。

对于普通文件,写操作始于cfo。如果打开文件时使用了O_APPEND,则每次写操作都将数据写入文件末尾。成功写入后,cfo增加,增量为实际写入的字节数。

实际自编:

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈