您的位置:首页 > 产品设计 > UI/UE

apue之文件IO

2013-10-15 21:36 323 查看
文件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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: