linux系统中文件I/O教程(2)
#include<unistd.h> //<unistd.h>必须最早出现,因为它可能会影响到其他头文件。#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
int main()
{
char* filename = ".//file";
char buf[100];
char buf1[5];
int fd;
printf("open a file to write\n");
if((fd = open(filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ))==-1)
{
perror("cannot open file\n");
return 1;
}
printf("open file successfully!\n");
printf("input a string:");
gets(buf);
//write intofile
if(write(fd,buf,strlen(buf)) !=strlen(buf))
{
perror("cannot write intofile\n");
return 1;
}
close(fd);
printf("open file to read.\n");
if((fd=open(filename,O_RDONLY)) == -1)
{
perror("cannot open thefile.\n");
return 1;
}
if(lseek(fd,3,SEEK_SET) == -1)
{
perror("lseek erroe\n");
return 1;
}
//read from the file
if(read(fd,buf1,4)==-1)
{
perror("read error.\n");
return 1;
}
printf("read from file is%s\n",buf1);
close(fd);
return 0;
}
执行与输出结果:
root@jb51:~$gcc -o io io.c
root@jb51:~$./io
open a file towrite
open filesuccessfully!
input a string:akxivbaslzkncxcasbxbwwvaidxbd
open file toread.
read from fileis ivba
linux 文件I/O教程(2)
下面介绍了linux中有关文件I/O的相关内容,内核使用三种数据结构表示打开的文件,他们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。
一,文件共享
内核使用三种数据结构表示打开的文件,他们之间的关系决定了在文件共享方面一个进程对另一个进程可能产生的影响。
1) 每个进程在进程表中都有一个记录项,记录项中包含一张打开文件描述表,可将其视为一个矢量,每个描述符占用一项。与每个文件描述符相关联的是:
a) 文件描述符标志
b) 指向一个文件表项的指针
2) 内核为所有打开文件维持一张文件表。每个文件表项包含:
a) 文件状态标志(读、写、读写、添些、同步和阻塞等)
b) 当前文件偏移量
c) 指向文件v节点表项的指针
3) 每个打开文件(或设备)都有一个v节点(v-node)结构。v节点包含了文件类型和对比文件进行各种操作的函数的指针。对于大多数文件,v节点还包含了该文件的i节点。i节点包含文件所有者、文件长度、文件所在的设备、指向文件实际数据块在磁盘上所在位置的指针等。
打开文件的内核数据结构
如果两个进程各自打开了同一个文件,则如图2所示。假定第一个进程在文件描述符3打开上该文件,而另一个进程在文件描述符4上打开该文件。每个进程都得得到一个文件表项,但对一个给定的文件只有一个v节点表项。每个进程都有自己的文件表项的一个理由是:使每个进程都有自己对该问价的当前偏移量。
现在对前一节文件I/O(1)的几个操作进一步说明:
1. 完成write之后,文件中当前偏移量即所增加的字节数。如果当前偏移量大于文件长度,则将i节点中当前文件长度设为当前文件偏移量。
2. 用O_APPEND打开一个文件,相应标志会被设置到文件状态标识中。每次写时,当前偏移量会被设置为i节点中的文件长度
3. lseek定位到文件尾端时,则文件当前偏移量会被设置为当前文件长度。
可能有多个文件描述符指向同一文件表项。调用dup和fork时都能看到这一点。
多个进程读同一文件能正确工作。但多个进程写同一文件时,可能产生预期不到的后果。可以利用原子操纵避免这种情况。
原子操作
一般而言,原子操作指的是由多部组成的操作。如果该院自地执行,要么执行完所以步骤,要么一步也不执行。
1. 添加至一个文件
考虑一个进程,它要讲数据添加到一个文件尾端。早期UNIX不支持open,所以可以如下实现: