文件IO与标准IO及非阻塞IO(非阻塞转)

来源:互联网 发布:2个excel表格数据对比 编辑:程序博客网 时间:2024/05/18 11:12

应用程序
——————————
内核 驱动 操作系统 系统移植

--------------------
硬件
API库
应用程序------>内核

系统编程 I/O 进程 网络

直接API 间接(减少了系统调用效率更高)
I/O分为 文件I/O----->内核标准I/O--------->内核

ps -axj 查看系统进程信息

#include "stdio.h"
#include "unistd.h"
#include "stdlib.h" //close() read() write() lseek()
#include "sys/types.h"//常用的宏
#include "fcntl.h" //open()
#include"string.h"
int main()
{
int fd;
int ret;
char str[]="ssddff";
char readstr[100];
memset(readstr,0,sizeof(readstr)); //数组清零
fd=open("/home/0414/abc",O_RDWR|O_TRUNC,0777);//返回文件描述符
if(fd==-1)
{
printf("open file failure\n");
exit(-1);
}
printf("open file sucess\n");
ret=write(fd,str,sizeof(str)); //返回真实写入的字符长度
lseek(fd,0,SEEK_SET); //修改当前文件位移量
printf("write %d byte in file abc\n",ret);
ret=read(fd,readstr,5); //返回读取到的字符长度
printf("read %d byte in file abc is %s\n",ret,readstr);
close(fd);
return 0;
}

原型 int open(const char *pathname, int flags, mode_t mode);
参数 pathname 被打开的文件名(可包括路径名)。


O_RDONLY:只读方式打开文件。

O_WRONLY:可写方式打开文件。(这三个参数互斥)
O_RDWR:读写方式打开文件。

O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三的参数为其设置权限。
O_EXCL:如果使用O_CREAT时文件存在,则可返回错误消息。这一参数可测试文件是否存在。
O_NOCTTY:使用本参数时,如文件为终端,那么终端不可以作为调用open()系统调用的那个进程的控制终端。
O_TRUNC:如文件已经存在,那么打开文件时先删除文件中原有数据。
O_APPEND:以添加方式打开文件,所以对文件的写操作都在文件的末尾进行。
mode 被打开文件的存取权限,为8进制表示法。

原型 off_t lseek(int fd,off_t offset,int whence);
参数 fd:文件描述符。
offset:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向前移,向后移)
whence
(当前位置基点): SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小。
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小
返回值 成功:文件的当前位移

-1:出错


通过一个简单的copy程序,完成文件的复制程序,了解基本的文件I/O文件读写的基本步骤

编写代码,实现相应的功能

打开源文件

打开目标文件

循环读取源文件并写入目标文件

关闭源文件

关闭目标文件

#include<stdio.h>
#include"unistd.h"
#include"stdlib.h"
#include"sys/types.h"
#include"fcntl.h"
#define max 256
int main(int argc,char *argv[])
{
int fd1;
int fd2;
int i;
char str[max];
if(argc != 3)
{
printf("the command error!");
exit(-1);
}
fd1 = open(argv[1],O_RDONLY);
if(fd1 == -1)
{
printf("open file failure\n");
exit(-1);
}
fd2 = open(argv[2],O_WRONLY|O_CREAT|O_APPEND|O_TRUNC,0777);
if(fd2==-1)
{
printf("open file failure\n");
exit(-1);
}
if(fd2 == -1)
{
printf("open file failure\n");
exit(-1);
}
do
{
i=read(fd1,str,max);
write(fd2,str,i);

}while(i==256);
return 0;

}

 

 

标准I/O有三种缓存1全缓存 2行缓存 3无缓存


inode---结构体---------指针---------
ext3 / \ |
| 磁盘块(文件内容,软链接指针) <
|
|
| inode-------------------
目录 | |
磁盘块(文件名链表形式)<----


软链接 ln -s xx cc “快捷方式”
硬链接 ln xx cc “对文件xx的备份”

一个小例子
#include<stdio.h>
int main()
{
printf("hello linux");
(____________________)
}
1 _exit(0); 2 fflush(stdout);_exit(0); 3 exit(0);

umask 取反后与设定的权限相与

打开函数文件描述符open(文件位置,打开方式,权限)
文件流指针fopen(文件位置,打开方式)
r只读文件存在 +读写 w写,没有文件创建,清零 a写没有文件创建,追加

fgetc(fp) fgets(buf,100,fp) fread(指针,size,num,fp)
fputc(int c,fp) fputs(buf,fp) fwrite(同上)
用以上3对函数编写复制函数

#include<stdio.h>
#include"stdlib.h"
int main(int argc,char *argv[])
{
FILE *fd1;
FILE *fd2;
char i;
if(argc != 3)
{
printf("the command error!");
  exit(-1);
}
fd1 = fopen(argv[1],"r");
if(fd1 == NULL)
{
printf("open file failure\n");
exit(-1);
}
fd2 = fopen(argv[2],"w");
if(fd2==NULL)
{
printf("open file failure\n");
exit(-1);
}
while((i=fgetc(fd1))!=EOF)
{
fputc(i,fd2);
}
return 0;

}

#include<stdio.h>
#include"stdlib.h"
#include"string.h"
#define N 100
int main(int argc,char *argv[])
{
FILE *fd1;
FILE *fd2;
int i=0;
char str[N];
if(argc != 3)
{
printf("the command error!");
exit(-1);
}
fd1 = fopen(argv[1],"r");
if(fd1 == NULL)
{
printf("open file failure\n");
exit(-1);
}
fd2 = fopen(argv[2],"w");
if(fd2==NULL)
{
printf("open file failure\n");
exit(-1);
}
while(fgets(str,N,fd1)!=NULL)
{
if(strlen(str)<N-1)
{
i++;
}
else
if(str[N-2]=='\n')
i++;

fputs(str,fd2);

}
printf("%d\n",i);

return 0;

}

#include<stdio.h>
#include"stdlib.h"
#define N 100
int main(int argc,char *argv[])
{
FILE *fd1;
FILE *fd2;
int i;
char str[N];
if(argc != 3)
{
printf("the command error!");
exit(-1);
}
fd1 = fopen(argv[1],"r");
if(fd1 == NULL)
{
printf("open file failure\n");
exit(-1);
}
fd2 = fopen(argv[2],"w");
if(fd2==NULL)
{
printf("open file failure\n");
exit(-1);
}
do
{
i=fread(&str,1,N,fd1);
fwrite(&str,1,i,fd2);
}while(i==N);

return 0;

}

原帖地址http://blog.csdn.net/ubuntulover/article/details/4443458

1.以非阻塞方式打开文件

调用open时,使用O_NONBLOCK选项即可。

实例:

//noblock.c

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

#define MAX 100000
#define LEN 1024

int main(int argc, char *argv[ ])
{
int fd1, fd2;
FILE *fp;
char buf[MAX];
int n, rest;
char *p = buf;
char content[LEN];

if(argc != 3){
printf("expect args/n");
exit(1);
}

fd1 = open(argv[1], O_RDONLY);
if(fd1 == -1){
perror("fail to read");
exit(1);
}

fp = fopen(argv[2], "w");
if(fp == NULL){
perror("fail to read");
exit(1);
}

fd2 = open("test.txt", O_WRONLY);
if(fd2 == -1){
perror("fail to read");
exit(1);
}

rest = read(fd1, buf, MAX);
printf("get %d bytes from %s/n", rest, argv[1]);

while(rest > 0){
errno = 0;
n = write(fd2, p, rest);

fprintf(fp, "write %d, errno %s/n", n, strerror(errno));
if(rest > 0){
p += n;
rest -= n;
}
}

printf("done/n");

return 0;
}

观察输出系统中调用出错原因的文件,可以看到很多错误号为EAGAIN的出错提示信息。

2.将一个打开的文件设置为非阻塞方式

用fcntl,先用F_GETFL得到状态标志字,之后用F_SETFL设置相应的位。

//noblock_fcntl.c

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

#define MAX 100000
#define LEN 1024

int main(int argc, char *argv[ ])
{
int fd1, fd2;
FILE *fp;
char buf[MAX];
int n, rest;
char *p = buf;
char content[LEN];
int flags;

if(argc != 3){
printf("expect args/n");
exit(1);
}

fd1 = open(argv[1], O_RDONLY);
if(fd1 == -1){
perror("fail to read");
exit(1);
}

fd2 = open(argv[2], O_WRONLY);
if(fd2 == -1){
perror("fail to read");
exit(1);
}

fp = fdopen(fd2, "w");
if(fp == NULL){
perror("fail to open");
exit(1);
}

flags = fcntl(STDOUT_FILENO, F_GETFL, 0);
if(flags == -1){
perror("fail to fcntl");
exit(1);
}
flags |= O_NONBLOCK;
if(fcntl(STDOUT_FILENO, F_SETFL, flags) == -1){
perror("fail to fcntl");
exit(1);
}

rest = read(fd1, buf, MAX);
printf("get %d bytes from %s/n", rest, argv[1]);

while(rest > 0){
errno = 0;
n = write(STDOUT_FILENO, p, rest);

fprintf(fp, "write %d, errno %s/n", n, strerror(errno));
if(rest > 0){
p += n;
rest -= n;
}
}

printf("done/n");

close(fd1);

fclose(fp);

return 0;
}

 

原创粉丝点击