文件 IO 2月18日学习笔记

标准IO和文件IO的区别:

1.标准IO是库函数,是对系统调用的封装

2.文件IO是系统调用,是Linux内核中的函数接口

3.标准IO是有缓存的

4.文件IO是没有缓存的

文件IO:

1.操作步骤:

打开 -> 读/写 -> 关闭

2.打开文件:

open 接口有两种形式

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

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

功能:

打开文件并且获得文件描述符

参数:

pathname:要打开的文件名

flags:标志位

O_RDONLY 只读

O_WRONLY 只写

O_RDWR 读写

O_APPEND 追加

O_ASYNC 异步IO

O_CREAT 文件不存在创建

O_TRUNC 文件存在截断(清0)

  • mode是一个无符号整数,用于设置新创建的文件的访问权限。只有在使用O_CREAT标志位创建新文件时才需要设置权限。可以使用S_IRUSRS_IWUSRS_IRGRPS_IWGRPS_IROTHS_IWOTH等标志位进行组合。

返回值:

成功返回文件描述符(很小的非负整数)

失败返回-1

新生成的文件描述符总是为尚未被使用的最小的非负整数

有三个预先定义的文件描述符:

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

这些文件描述符通常保留给应用程序的标准输入、标准输出和标准错误流。

cpp 复制代码
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

int main(void)
{
	int fd = 0;
	
//	0664
//	rw-rw-r--
//0664:该参数将设置新创建文件的访问权限为 "rw-rw-r--",其中:
//0表示权限位的起始标志。
//6表示文件所有者具有读写权限。
//4表示文件所有者所在组具有读权限。
//4表示其他用户具有读权限。
//	fd = open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);		//w
//	fd = open("a.txt", O_RDONLY);								//r
//	fd = open("a.txt", O_RDWR);									//r+
//	fd = open("a.txt", O_RDWR | O_CREAT | O_TRUNC, 0664);		//w+	
//	fd = open("a.txt", O_WRONLY | O_CREAT | O_APPEND, 0664);	//a
	
	while (1)
	{
		fd = open("a.txt", O_RDWR | O_CREAT | O_APPEND, 0664);		//a+
		if (-1 == fd)
		{
			perror("fail to open");
			return -1;
		}
	
		printf("fd = %d\n", fd);
	}

	return 0;
}

3.关闭文件:

close

int close(int fd);

功能:

将fd对应的文件描述符关闭

4.读写:

read/write

1.write

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

功能:

向fd对应的文件中写入buf指向的count个字节

参数:

fd:文件描述符

buf:写入数据空间首地址

count:写入的字节数

返回值:

成功返回实际写入字节数

失败返回-1

cpp 复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
	int fd = 0;
	char tmpbuff[4096] = {"hello world"};

	fd = open("a.txt", O_WRONLY | O_TRUNC | O_CREAT, 0664);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	write(fd, tmpbuff, strlen(tmpbuff));

	close(fd);

	return 0;
}

2.read

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

功能:

从文件描述符fd对应的文件中读取count个字节存放到buf开始的空间中

参数:

fd:文件描述符

buf:存放数据空间的首地址

count:想要读取数据字节数

返回值:

成功返回实际读到的字节数

失败返回-1

读到文件末尾返回0

cpp 复制代码
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(void)
{
	int fd = 0;
	ssize_t nret = 0;
	char tmpbuff[4096] = {0};

	fd = open("a.txt", O_RDONLY);
	if (-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	nret = read(fd, tmpbuff, sizeof(tmpbuff));
	printf("nret = %ld\n", nret);
	printf("tmpbuff = %s\n", tmpbuff);

	close(fd);

	return 0;
}

eg1:利用read和write实现文件内容的拷贝(将src.jpg中的内容拷贝到dst.jpg文件中)

cpp 复制代码
#ifndef __HEAD_H__
#define __HEAD_H__

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

#endif
cpp 复制代码
#include "head.h"

int main(int argc, const char *argv[])
{
	int fsrc = 0;
	int fdst = 0;
	char tmpbuff[4096] = {0};
	ssize_t nret = 0;

	if (argc != 3)
	{
		fprintf(stderr, "Usage:./a.out srcfilename dstfilename\n");
		return -1;
	}

	fsrc = open(argv[1], O_RDONLY);
	if (-1 == fsrc)
	{
		perror("fail to open");
		return -1;
	}

	fdst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0664);
	if (-1 == fdst)
	{
		perror("fail to open");
		return -1;
	}

	while (1)
	{
		nret = read(fsrc, tmpbuff, sizeof(tmpbuff));
		if (nret <= 0)
		{
			break;
		}

		write(fdst, tmpbuff, nret);
	}
	
	close(fsrc);
	close(fdst);

#if 0
	int i = 0;

	printf("argc = %d\n", argc);
	for (i = 0; i < argc; i++)
	{
		printf("argv[%d] = %s\n", i, argv[i]);
	}
#endif

	return 0;
}

eg2:某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的------假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入格式:

输入在第一行给出正整数 N,取值在(0,105];随后 N 行,每行给出 1 个人的姓名(由不超过 5 个英文字母组成的字符串)、以及按 yyyy/mm/dd(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。

输出格式:

在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。

cpp 复制代码
#include "head.h"

typedef struct person
{
	char name[8];
	char birthday[12];
}person_t;

int main(void)
{
	person_t a[100000];
	int n = 0;
	int i = 0;
	int cnt = 0;
	char maxvalue[12] = {"2014/09/06"};
	char minvalue[12] = {"1814/09/06"};
	int curmax = 0;
	int curmin = 0;

	scanf("%d", &n);
	
	for (i = 0; i < n; i++)
	{
		scanf("%s%s", a[i].name, a[i].birthday);
	}

	for (i = 0; i < n; i++)
	{
		if (strcmp(a[i].birthday, maxvalue) <= 0 && strcmp(a[i].birthday, minvalue) >= 0)
		{
			cnt++;
			
			if (1 == cnt)
			{
				curmax = curmin = i;
			}
			
			if (strcmp(a[i].birthday, a[curmax].birthday) > 0)
			{
				curmax = i;
			}

			if (strcmp(a[i].birthday, a[curmin].birthday) < 0)
			{
				curmin = i;
			}
		}
	}

	printf("%d %s %s\n", cnt, a[curmin].name, a[curmax].name);

	return 0;
}
相关推荐
虾球xz1 小时前
游戏引擎学习第292天:实现蛇
c++·学习·游戏引擎
wishfly2 小时前
vscode - 笔记
ide·笔记·vscode
黄鹂绿柳3 小时前
Vue+Vite学习笔记
vue.js·笔记·学习
985小水博一枚呀7 小时前
【AI大模型学习路线】第二阶段之RAG基础与架构——第七章(【项目实战】基于RAG的PDF文档助手)技术方案与架构设计?
人工智能·学习·语言模型·架构·大模型
FakeOccupational7 小时前
计算机科技笔记: 容错计算机设计05 n模冗余系统 TMR 三模冗余系统
笔记·科技
hello1114-8 小时前
Redis学习打卡-Day3-分布式ID生成策略、分布式锁
redis·分布式·学习
小Tomkk8 小时前
2025年PMP 学习二十 第13章 项目相关方管理
学习·pmp·项目pmp
独行soc9 小时前
2025年渗透测试面试题总结-百度面经(题目+回答)
运维·开发语言·经验分享·学习·面试·渗透测试·php
海棠蚀omo9 小时前
C++笔记-红黑树
开发语言·c++·笔记
ysy16480672399 小时前
03算法学习_977、有序数组的平方
学习·算法