apue之文件IO

文件IO

1、文件IO与标准IO

         标准IO

            标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存。

    (1)全缓存:当填满标准IO缓存后才进行实际的IO操作。 
    (2)行缓存:当输入或输出中遇到新行符时,标准IO库执行IO操作。 
    (3)不带缓存:stderr就是了。

        文件IO:

        文件IO称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于linix或unix平台。

    区别

        首先:两者一个显著的不同点在于,标准I/O默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区(读写模式下将建立两个缓冲区),还创建了一个包含文件和缓冲区相关数据的数据结构。低级I/O一般没有采用缓冲,需要自己创建缓冲区,不过其实在linix或unix系统中,都是有使用称为内核缓冲的技术用于提高效率,读写调用是在内核缓冲区和进程缓冲区之间进行的数据复制。

        其次从操作的设备上来区分,文件I/O主要针对文件操作,读写硬盘等,它操作的是文件描述符,标准I/O针对的是控制台,打印输出到屏幕等,它操作的是字符流。对于不同设备得特性不一样,必须有不同api访问才最高效。

2、文件IO的主要函数:

    open, close, read, write, lseek、hup, dup2, fcntl, pread, pwrite    

    open函数:

#include <fcntl.h>
 int open(const char * pathName, int flags, .../*mode_t mode*/);

 成功返回文件描述符,失败返回-1
 返回的文件描述符的当前未使用的最小描述符
   flags:  
  必选参数:O_RDONLY、O_WDONLY、O_RDWR
  可选参数:O_APPEND、O_CREAT、O_EXCL、O_TRUNC、O_NOBLOCK、O_NOCTTY
 
close函数:

#include <unistd.h>
int close(int fildes);
 成功返回0, 失败返回-1

read函数:

#include <unistd.h>
ssize_t read(int fd, void * buf, size_t len);


 参数:
      fd:打开的文件描述符;
      buf:读取数据存放缓冲区;
      len:缓冲区的大小
 return:
      成功返回读取到的缓冲区大小
      0:表示读取到文件末尾
      -1:调用失败
  

write函数:

#include <unistd.h>
ssize_t write(int fd, const void * buf, size_t len);

 参数:
      fd:打开的文件描述符
      buf:将要写的数据缓冲
      len:数据缓冲区的大小
  

lseek函数:

off_t lseek(int fd, off_t offset, int whence);
 参数:
      fd:打开的文件描述符
      offset:偏移位置大小
      whence:偏移位置的基准
         whence的取值:
              SEEK_CUR:offset表示相对于当前位置的偏移量
              SEEK_SET: offset表示相对于文件开始位置的偏移量
              SEEK_END: offset表示相对于文件结束位置的偏移量    

 实例1:模仿linux/unix的copy指令:

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

const int MAX_BUF_LEN = 4096;

int main(int argc, char * argv[])
{
	if(3 != argc)
	{
		printf("命令格式不正确!\n");
		return -1;
	}
	int fdRead = open(argv[1], O_RDONLY | O_CREAT | O_EXCL, 0664);
	if(-1 != fdRead)
	{
		printf("源文件不存在!\n");
		close(fdRead);
		char buf[255] = {0};
		sprintf(buf, "rm %s", argv[1]);
		system(buf);
		return -2;
	}
	fdRead = open(argv[1], O_RDONLY);
	if(-1 == fdRead)
	{
		printf("open error:源文件打开错误!\n");
		return -3;
	}
	int fdWrite = open(argv[2], O_WRONLY | O_CREAT | O_EXCL, 0664);
	if(-1 == fdWrite)
	{
		printf("open error: 创建目标文件失败!\n");
		fdWrite = open(argv[2], O_WRONLY | O_TRUNC);
		if(-1 == fdWrite)
		{
			return -4;
		}
	}
	while(true)
	{
		char buf[MAX_BUF_LEN] = {0};
		int nReadLen(0), nWriteLen(0);

		nReadLen = read(fdRead, buf, MAX_BUF_LEN);
		if(nReadLen <= 0)
		{
			printf("读取源文件出错!\n");
			break;
		}
		
		nWriteLen = write(fdWrite, buf, nReadLen);
		if(-1 == nWriteLen)
		{
			printf("生成目标文件出错!\n");
			return -5;
		}
	}
	
	return 0;
}

 

原子操作:
ssize_t pread(int fd, void * buf, size_t len, off_t offset);
ssize_t pwrite(int fd, const void * buf, size_t len, off_t offset);

你可能感兴趣的:(Uinx环境高级编程,copy指令,文件IO,标准IO)