现在的位置: 首页 > 综合 > 正文

unix环境下文件I/O函数

2018年03月20日 ⁄ 综合 ⁄ 共 2641字 ⁄ 字号 评论关闭

1.符号描述符

首先要记住,对于所有打开的文件系统都是通过文件描述符来引用的。文件描述符是一个非负整数。在unix系统中(大部分系统也是这样),用0代表标准输入流,用1代表标准输出流,用2代表标准错误流。在头文件<unistd.h>中定义了STDIN_FILENO,STDOUT_FILENO以及STDERR_FILENO。


2.open函数

open函数可以打开或者创建一个文件,函数原型如下

#include <fcntl.h>
int open(const char *pathname,int oflag,.../*mode_t mode*/)
返回值:若成功返回文件描述符,若出错返回-1

pathname不用说指的是文件的路径名,注意使用'/'来间隔目录。

对于第二个参数oflag,以下是需要使用到fcntl.h中的常用参数:

O_RDONLY(只读)
O_WRONLY(只写)
O_RDWR(读写)
//以上这三个常量只能选择一个
O_APPEND(末尾追加)
O_CREAT(如果文件不存在则创建文件,这时需要使用第三个参数mode,指定该文件的访问权限位)
O_EXCL(如果文件存在,则出错,用来检测文件是否存在)
O_TRUNC(如果文件存在,而且为只读或只写打开,则将其长度截短为1)

 对于open函数,当且仅当创建新文件时才使用的三个参数。由open返回的文件描述符一定是最小的未用的文件描述符,这可以用先关闭标准输出,然后打开文件,则文件的描述符为1。


3.creat函数

creat函数用来创建一个新文件,函数原型如下

#includ <fcntl.h>
int creat(const *pathname,mode_t mode)
返回值:若成功则返回为只写打开的文件描述符,否则返回-1
等效于open(pathname.O_WRONLY | O_CREAT | O_TRUNC,mode)

由于creat只能以写的方式打开文件,要想读取该文件需要creat,close,open。可以直接采用如下方式open(pathname,O_RDWR | O_CREAT |O_TRUNC,mode)。


4.close函数

关闭文件并释放其所占资源,函数原型如下

#include<unistd.h>
int close(int filedes)
返回值:成功返回0,否则返回-1

5.lseek函数

每个打开的文件在内核中都维护了一个“当前文件偏移量”,指的是从文件开始处计算的字节数。除非使用O_APPEND,否则偏移量一般都为0。

调用lseek显示地为一个打开的文件设置偏移量,函数原型如下

#include <unistd.h>
off_t lssek(int filedes, off_t offset, int whence)
返回值:若成功则返回新的文件偏移量,若出错则返回-1
//若whence为SEEK_SET,则将文件的偏移量设置为距文件开始处offset个字节。////
//若whence为SEEK_CUR,则将文件的偏移量设置为当前值加offset,offset可正可负。
//若whence为SEEK_END,,则将文件的偏移量设置为文件长度加offse,offset可正可负,
//注意文件偏移量可以大于当前文件长度,系统并不会为之间的空洞分配磁盘空间,只为新的数据分配磁盘空间。


6.read函数

调用read函数从打开的文件中读取数据,函数原型如下:

#include <unistd.h>
ssize_t read(int filedes,void *buf,size_t nbytes)
返回值:若成功返回读到的字节数,若已到文件结尾则返回0,若出错返回-1

7.write函数

调用write函数向打开的文件写数据,函数原型如下:

#include <unistd.h>
ssize_t write(int filedes,const void* buff,size_t nbytes)
返回值:若成功返回已写的字节数,若出错返回-1

其返回值通常与参数nbytes相同,否则表示出错。常见的出错原因包括:磁盘已经写满、超过了文件的最大长度限制。对于普通文件,写操作从文件的当前偏移量处开始。执行一次成功的写之后,文件的偏移量增加实际写的字节数。

8.文件I/O函数总结

1).进程终止时,uinx系统内核会关闭该进程的所有打开的文件描述符,所以可以不用必须关闭输入和输出文件(最好还是自行关闭,以免造成内存资源的浪费)。

2).上述的open、creat、close、lseek、read、write都是系统内核函数,对文本文件和二进制文件没有区别。

3).用以下程序来实践一下。

#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#define BUFFSIZE 2048

int main(int argc,char **argv)
{
	
	int fd,num;
	char buf[BUFFSIZE];
	char *fileName = "./1.txt";
	off_t pos;
	
	// 在当前目录下以读写的方式打开文件,若文件不存在则创建文件 
	if(( fd = open(fileName,O_RDWR | O_CREAT | O_TRUNC)) < 0)
	{
		printf("open file fail%s\n",fileName);
		exit(1);
	}
	
	//从键盘读入数据,再写入到文件中
	while((num = read(STDIN_FILENO,buf,BUFFSIZE)) > 0)
	{
		//如果为"stop"则停止输入
		if(strncmp(buf,"stop",4)==0)
		{
			printf("write data stop\n");
			break;
		}
		if(write(fd,buf,num) != num)
		{
			printf("write data fail\n");
			exit(1);
		}
		printf("write data success\n");
	}
	
	//在文件最后的第10个字节出插入"?"
	if((pos = lseek(fd,-10,SEEK_END)) == -1)
	{
		printf("lssek fail\n");
		exit(1);	
	}	
	if(write(fd,"?",1) != 1)
	{
		printf("read fail\n");
		exit(1);
	}
	
	return 0;
}

注意:这里的文件creat时没有设置权限,所以读取时要用到root权限。运行结果如下:(可以尝试把偏移量设置为10,运行下结果看看)

  

抱歉!评论已关闭.