●实验目的:
学会创建文件,并制定文件访问属性;
学会使用C库函数和Linux系统调用,并理解它们的区别。
●实验要求:
编写应用程序,创建一可读可写的文件;
使用库函数,实现文件copy功能。
●实验器材:
硬件: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增加,增量为实际写入的字节数。
实际自编:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。