注意:以下实验在Linux Ubuntu 16.04环境下进行
【一、打开并得到文件描述符】
#include <fcntl.h>
main()
{
//定义三个整型变量fd1,fd2,fd3
int fd1,fd2,fd3;
//以读写方式打开f1,f2,f3三个文件,返回的值分别赋值给fd1,fd2,fd3
//open()函数:当打开文件成功时,返回一个文件描述符;当打开文件失败时,返回-1,并且errno为错误码
fd1 = open("f1",O_RDWR);
fd2 = open("f2",O_RDWR);
fd3 = open("f3",O_RDWR);
//打印输出fd1,fd2,fd3的值
printf("fd1=%d\nfd2=%d\nfd3=%d\n",fd1,fd2,fd3);
//分别关闭文件描述符为fd1,fd2,fd3的文件
close(fd1);
close(fd2);
close(fd3);
}
【实验结果】
0,1,2被系统占用,0是标准输入,1是标准输入,2是标准错误,所以文件描述符从3开始依次往后记录,就得到了这样的结果。
【二、读写文件】
#include <fcntl.h>
main()
{
//定义整型变量fd
int fd;
//定义整型变量num
int num;
//定义缓冲区数组buf,大小为20
char buf[20];
//以只读方式打开文件名为f1的文件,返回的值赋值给fd
fd = open("f1",O_RDONLY);
//如果打开文件失败
if(fd==-1)
{
//打印错误信息
perror("open");
//返回
exit(1);
}
//从文件描述符为fd的文件中读数据,一次读20个字节,到缓冲区buf中
//read()函数:执行成功时,返回的是实际读回数据的字节数;当失败时,返回-1,并且errno为错误码
while((num=read(fd,buf,20))>0)
{
//将buf缓冲区中的内存写入到标准输出中,每次写num个字节,如果写入的数据小于num,打印有问题
//write()函数:执行成功时,返回的时实际写入数据的字节数;当失败时,返回-1
if(write(1,buf,num)<num)
printf("write 1 less than should\n");
}
//关闭文件描述符为fd的文件
close(fd);
}
在程序中,以只读方式打开文件f1,如果打开成功,则进入一个循环。循环每次通过read()从f1中读取20字节的数据,并写入屏幕设备文件中,当read()返回的结果等于0或者-1时循环结束。
在循环过程中,如果向屏幕设备文件写入的字节数不等于从f1文件中读出的字节数时,给出相应提示。
循环结束后,关闭f1文件。
【三、文件基本I/O操作】
#include <unistd.h>
#include <fcntl.h>
main(){
//定义两个整型变量fd1,fd2
int fd1,fd2;
//定义整型变量num
int num;
//定义缓冲区数组,大小为20
char buf[20];
//以读写方式打开文件名为f1的文件,并将文件清空,将返回值复制给fd1
fd1 = open("f1",O_RDWR|O_TRUNC);
//如果打开失败
if(fd1==-1){
//输出错误信息
perror("open");
//返回
exit(1);
}
//输出fd1的文件描述符
printf("fd1 is %d \n",fd1);
//以读写方式打开文件名为f1的文件,将返回值赋值给fd2
fd2 = open("f1",O_RDWR);
//如果打开失败
if(fd2==-1){
//输出错误信息
perror("open");
//返回
exit(1);
}
//输出fd2的文件描述符
printf("fd2 is %d \n",fd2);
//向文件描述符为fd1的文件中写入"hello world!"
num = write(fd1,"hello world!",12);
//输出向f1中写入了多少数据
printf("fd1:write num = %d bytes into f1\n",num);
//从文件名为fd2的文件中读取20个字节的数据并放入buf缓冲区中,并将返回值复制给num
//read()函数:执行成功时:返回的时实际读回数据的字节数;当失败时,返回-1,并且errno为错误码
num = read(fd2,buf,20);
//将0赋值给buf[num],即第buf[12]=0
buf[num] = 0;
//输出从文件f1中读了多少数据
printf("fd2:read %d bytes from f1:%s \n",num,buf);
//关闭文件描述符为fd1的文件
close(fd1);
//关闭文件描述符为fd2的文件
close(fd2);
}
在程序中,两次使用open()打开文件f1。虽然两次打开的是同一个文件,但由于这是两次独立的open()操作,每一次open()操作打开文件时,都会在系统的打开文件表中登记一个不同的表项,并在该进程的用户文件描述符中也会登记一个不同的表项。因此两次open()操作得到了两个不同的文件描述符。这两个文件描述符对应着文件表中的两个不同的表项。由于文件的读写指针保存在文件表表项中,因此两个文件描述符都拥有各自独立的文件读写指针。
两次open()执行之后,两个文件描述符对应的读写指针都指向f1的开始位置。此时通过文件描述符fd1向文件f1中写入了12个字符“hello world!”,成功写入之后其读写指针为12。而这时另一个文件描述符fd2对应的读写指针仍为0,指向文件的开始位置。因此接下来通过fd2从文件中读数据时,会将刚才写入的字符串读出。