2024.12.10(作业)文件IO

作业:使用read和write实现拷贝文件,将1.txt内容前一半拷贝给2.txt后一半拷贝给3.txt。

#include <myhead.h>

int main(int argc, const char *argv[])
{
	//作业:使用read和write实现拷贝文件,
	//将1.txt内容前一半拷贝给2.txt后一半拷贝给3.txt。
	int fd1,fd2,fd3;
	fd1 = open("./1.txt",O_RDONLY); 				//只读方式打开
	fd2 = open("./2.txt",O_CREAT|O_TRUNC|O_RDWR,664); 	//创建读写方式打开
	fd2 = open("./3.txt",O_CREAT|O_TRUNC|O_RDWR,664); 	//创建读写方式打开
	if(fd1 == -1||fd2 == -1||fd3 == -1)
	{
		perror("open");
		return -1;
	}
	int buff[100];
	int len = lseek(fd1,0,SEEK_END);  				//总长度
	lseek(fd1,0,SEEK_SET); 							//指针偏移回开头
	int len1 = 0,i=0;
	for(;len1+i<len/2;len1+=i)
		{
			i=read(fd1,buff,sizeof(buff));
			write(fd2,buff,i);
		}
			i=read(fd1,buff,(len/2-len));
			write(fd2,buff,i);
	int j=1;
	while(j!=0)
	{
		j=read(fd1,buff,sizeof(buff));		
		write(fd3,buff,j);
	}
	close(fd1);
	close(fd2);
	close(fd3);
	printf("拷贝成功\n");
	return 0;
}

1、文件IO(系统调用)

文件IO:基于系统调用的API函数接口。

特点:每一次调用文件IO,系统都会从用户态到内核态之间切换,效率很低。

作用:后期学习进程间通信,管道,SOCKET套接字通信,都会用到文件IO。

2.文件结构体

文件结构体成员 int _fileno就是打开文件后返回给用户的文件描述符。

struct _IO_FILE {

char* _IO_buf_base; /* Start of reserve area. */

char* _IO_buf_end; /* End of reserve area. */

int _fileno;//文件描述符,也称为文件的句柄。

};

3.文件描述符

3、文件描述符:

1、本质上是一个非负整数,类似于标准IO打开文件时的 fp指针。

2、进程执行时默认打开3个文件描述符0(stdin),1(stdout),2(stderr)。

3、文件描述符可以使用ulimit -a查看打开文件个数。使用 ll 查看文件权限。

4、分配原则,按照最小未分配原则,而且每一个终端进程打开文件的个数是有限制的最多是1024个文件。

标准输入,标准输出,标准错误文件描述符

5,可以使用 chmod 664 test/修改文件或者文件夹的权限。

ubuntu@ubuntu:IO-2$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7558
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024最多打开1024个文件
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7558
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

4、open和close

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

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

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

功能:打开或者创建文件。

参数1:文件的路径和文件名

参数2:打开或者创建文件时的语义

        O_CREAT:创建文件

        O_RDONLY:只读模式

        O_WRONLY :只写模式

        O_RDWR:读写模式

        O_EXCL:如果文件存在就报错

        O_TRUNC:清空文件内容。

        O_APPEND:追加写的方式

以上选项可以按照位或方式组合使用。        

        参数3:可选项

                如果参数2有O_CREAT或者O_TMPFILE,参数3必须加上创建时的权限,如果没有参 数3直接省略。

        参数3是文件或者文件夹创建时的权限。

        返回值:成功返回文件描述符,失败返回-1,并置位错误码。

         文件夹的默认最大权限是775,文件的默认最大权限是664。

eg: w:open("./1.txt",O_CREAT|O_TRUNC|O_WRONLY,0664);

         r:open("./1.txt",O_RDONLY);

         r+:open("./1.txt",O_RDWR);         w+:open("./1.txt",O_CREAT|O_TRUNC|O_RDWR,0664);         a:open("./1.txt",O_CREAT|O_APPEND|O_WRONLY,0664);         a+:open("./1.txt",O_CREAT|O_APPEND|O_RDWR,0664);

还可以有以下使用规则:

open("./1.txt",O_CREAT|O_EXCL|O_RDWR,0664);//只创建读写文件,如果文件存在就报错。

open("./1.txt",O_CREAT|O_EXCL|O_TRUNC|O_WRONLY,0664);//只写创建,清空打开文件,如果文件存在就报错 int close(int fd);

功能:关闭open函数打开的文件描述符。

参数:文件描述符(文件句柄)

返回值:成功返回0,失败返回-1,并置位错误码。

文件夹的默认最大权限是775,文件的默认最大权限是664

如果我们在创建文件夹时给出的权限是777,那么由于终端的umask=0002,所以最终系统给的最大权限就是775.

如果我们在创建文件时给出的权限是666,那么由于终端的umask=0002,所以最终系统给的最大权限就是664.

5、文件描述符分配

1. 打开文件:使用 open函数打开文件时,操作系统会为该文件分配一个文件描述符。文件描述符是一个整数,通常从0开始。

2. 标准文件描述符:

  • 文件描述符 0:标准输入(stdin)
  • 文件描述符 1:标准输出(stdout)
  • 文件描述符 2:标准错误(stderr)

3. 分配过程:

  • 当您打开一个新文件时,操作系统会查找当前进程中未使用的最小文件描述符,并将其分配给新打开的文件。
  • 如果所有文件描述符都已被使用,您将无法打开更多文件,直到关闭某些文件或进程结束。
  • 关闭文件:使用 close函数关闭文件时,操作系统会释放该文件描述符,使其可以被后续的文件打开操作重新使用。

验证多次打开关闭文件,查看文件描述符数值:

6、write和read

#include <unistd.h>

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

        功能:向fd指向的描述符写入内容,写count个字节

        参数1:文件描述符

        参数2:写入的内容

        参数3:写入的字节数。

        返回值:成功返回写入的字节个数,如果什么都没写入返回0,失败返回-1,并置位错误码。

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

        功能:从fd指向的文件读取count个字节到buf中

        参数1:文件描述符

        参数2:读取的内容

        参数3:读取的字节数。

        返回值:成功返回读取的字节数,读取到文件末尾返回0,失败返回-1,并置位错误码。

7、lseek

#include <sys/types.h>

#include <unistd.h>

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

        功能:移动文件光标

        参数1:文件描述符

        参数2:偏移量

                >0:往后偏移

                <0:往前偏移

                =0:不偏移

        参数3:偏移的起始位置

                SEEK_SET:从文件的开头开始偏移

                SEEK_CUR:从当前位置开始偏移

                SEEK_END:从文件末尾开始偏移

        返回值:成功返回文件开头到光标之间的字节数,失败返回-1并置位错误码。

eg:将光标偏移到文件末尾

        int len = lseek(fd,0,SEEK_END);

        len是文件的总大小。

8、dup和dup2

1、dup和dup2在赋值(复制)新描述符时新旧描述符都共享光标

2、dup会产生新的描述符遵循最小未分配原则

3、dup2不会产生新的描述符,只会先将新描述符指向的文件关闭,然后重定向新描述符到旧描述符文件。

#include <unistd.h>

        int dup(int oldfd);

        功能:将文件描述符拷贝一份生成新的描述符,新旧文件描述符指向同一个文件,并且共享文件光标。

        参数:旧的描述符。

        返回值:成功返回创建的新描述符,失败返回-1,并置位错误码。

        int dup2(int oldfd, int newfd);

        功能:将新的描述符重定向给旧的描述符,新的描述符指向的文件会被关闭,然后新 旧描述符都指向旧的文件,并且共享文件光标。

        注意:dup2不会像dup那样产生新描述符并且也不会遵循最小未分配原则。

        返回值:成功返回原本新描述符,但是新描述符值没有变化(重定向到旧的描述符),失败返回-1并置位错误码。


思维导图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值