IO进程(文件IO)

1.什么是文件IO

1.1概念:

文件IO又称为系统IO,是系统调用,是操作系统提供的接口函数。

如图:标准IO:你的程序在在运行的时候,如果想要读取磁盘内容,就要使用C库函数接口,然后通过内核的系统调用取去驱动程序把磁盘文件传输给你的程序;如果这个时候你使用文件IO,就不再调用C库函数接口,而是直接使用系统调用接口,速度上是快了很多,但是也是有别的缺点(后面说)。

1.2 特点

  1. 没有缓冲机制,每次调用都会引起系统调用,(标准库中的函数会在用户空间维护一个缓冲区,当程序写入数据时,先存储到用户空间的缓冲区,等缓冲区满了或满足特定条件时,才通过系统调用一次性将数据提交到内核,减少系统调用的次数,提高效率。
  2. 围绕文件描述符进行操作,非负整数(>=0),依次分配
  3. 文件IO默认打开三个文件描述符,分别是0(标准输入),1(标准输出),2(标准错误)(和标准IO的流类似)
  4. 操作除了目录以外的任意类型的文件: b c - l s p(七个文件类型)
  5. 可移植性相对较弱(就是跨平台能力,因为直接使用系统调用,不同的操作系统的系统调用函数是不同,所以你的程序到别的操作系统可能就跑不了)

思考:

1.一个进程的文件描述符最大到几?最多能打开多少个文件描述符?最多能打开多少个文件?

答:一个进程的文件描述符最大到1023(0-1023) ,最多能打开1024个文件描述符, 最多能打开1021(1024-3)个文件。

2.如果我打开三个文件,描述符分别是: 3 4 5

关闭3和5以后, 再打开一个别的文件,描述符是几?

答:是3(从最小开始分配)

 2.函数接口

2.1打开关闭文件open()和close()

2.1.1 open()

头文件:#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);

功能:打开文件

参数:pathname:文件路径名

           flags:打开文件的方式

                O_RDONLY:只读

                O_WRONLY:只写

                O_RDWR:可读可写

                O_CREAT:不存在创建

                O_TRUNC:存在清空

                O_APPEND:追加

返回值:成功:文件描述符

              失败:-1

重点:当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限(就是如果你是第一次创建文件(这个文件不存在),那么必须给这个文件添加权限(flags),并且以你第一次创建给它的权限为准,权限不会再通过这个函数而改变除非你删除或者终端使用chmod改变权限)

int open(const char *pathname, int flags, mode_t mode);

最后权限 = mode & (~umask)

例如:指定的权限0666(8进制)

最终权限: 0666 & (~umask) = 0666 & (~0002)=0666 & 0775 = 0664

注意:通过umask命令可以查看umask文件权限掩码

文件IO和标准IO的打开方式的对应关系

标准IO

文件IO

r

O_RDONLY

只读

r+

O_RDWR

可读可写

w

O_WRONLY | O_CREAT|O_TRUNC, 0777

只写,不存在创建,存在则清空

w+

O_RDWR | O_CREAT|O_TRUNC, 0777

可读可写,不存在创建,存在则清空

a

O_WRONLY | O_CREAT| O_APPEND, 0777

只写,不存在创建,存在追加

a+

O_RDWR | O_CREAT| O_APPEND, 0777

可读可写,不存在创建,存在追加

2.1.2 close()

头文件:#include <unistd.h>

int close(int fd);

功能:关闭文件

参数:fd:文件描述符

 例:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
	int file = open("2",O_RDONLY,0666);        //打开文件
	if(file < 0){                              //判断是否成功打开
		perror("open err");
		return -1;
	}
	printf("fd:%d\n",file);                    //打印文件标识符(3)             
	file = close(file);                        //关闭文件 
	printf("fd:%d\n",file);
	return 0;
}

 

2.2 读写文件read()和write()

头文件:#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

功能:从一个已打开的可读文件中读取数据

参数: fd 文件描述符

            buf 存放位置

            count 期望的个数

返回值:成功:实际读到的个数(小于期望值说明实际没这么多)

                         返回0,表示读到文件结尾

               失败:返回-1:表示出错,并设置errno号

ssize_t write(int fd, const void *buf, size_t count);

功能:向指定文件描述符中,写入 count个字节的数据。

参数:fd 文件描述符

           buf 要写的内容

           count 期望写入字节数

返回值:成功:实际写入数据的个数

              失败 : -1

 2.3 文件定位操作 lseek()

off_t lseek(int fd, off_t offset, int whence);

功能:设定文件的偏移位置

参数:fd:文件描述符

offset: 偏移量

正数:向文件结尾位置移动

负数:向文件开始位置

whence: 相对位置

SEEK_SET 开始位置

SEEK_CUR 当前位置

SEEK_END 结尾位置

补充:和fseek一样其中SEEK_SET,SEEK_CURSEEK_END和依次为012.

返回值:成功:文件的当前位置

失败:-1

例:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	int fd;
	fd = open("2",O_RDWR|O_CREAT|O_TRUNC);	//可读可写,如果不存在创建存在清空(w+)
	if(fd < 0){
		perror("open err");
		return -1;
	}
	char buf[30] = "";
	write(fd,"hello\n",6);            //写入
	write(fd,"hello\n",6);
	write(fd,"hello",5);
	lseek(fd,0,SEEK_SET);             //定位到文件开头
	read(fd,buf,sizeof(buf));         //读取
	printf("%s\n",buf);               //打印读取的内容
	return 0;
}

练习:

文件IO实现cp功能。cp 源文件 新文件名

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, const char *argv[])
{
	if(argc != 3){
		perror("argc err");
		return -1;
	}
	int fd = open(argv[1],O_RDWR);
	if(fd < 0){
		perror("open1 err");
		return -1;
	}
	int fdnew = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0666);      //打开新文件(w+)
	if(fdnew < 0){
		perror("open2 err");
		return -1;
	}
	char buf[30] = "";
	while(read(fd,buf,1) != 0){            //一个字符一个字符读取
		write(fdnew,buf,1);                //一个字符一个字符输出到新文件
	}
	close(fd);
	close(fdnew);
	return 0;
}

标准IO和文件IO总结

标准IO

文件IO

概念

C库中定义一组用于输入输出的函数

posix中定义的一组用于输入输出的函数

特点

  1. 有缓冲机制
  2. 围绕流进行操作:FILE *
  3. 默认打开三个流:stdin/stdout/stderr
  4. 只能操作普通文件
  5. 可移植性相对较强
  1. 无缓冲机制
  2. 围绕文件描述符操作:非负整数
  3. 默认打开三个文件描述符:0/1/2
  4. 可以操作除了目录以外任意类型文件
  5. 可移植性相对较弱

函数

打开文件:fopen

关闭文件: fclose

读文件:fgets/fread

写文件:fputs/fwrite

定位操作:rewind/fseek/ftell

打开文件:open

关闭文件:close

读文件: read

写文件:write

定位操作:lseek

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值