标准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_IRUSR
、S_IWUSR
、S_IRGRP
、S_IWGRP
、S_IROTH
、S_IWOTH
等标志位进行组合。
返回值:
成功返回文件描述符(很小的非负整数)
失败返回-1
新生成的文件描述符总是为尚未被使用的最小的非负整数
有三个预先定义的文件描述符:
- 0:标准输入文件描述符(stdin)
- 1:标准输出文件描述符(stdout)
- 2:标准错误文件描述符(stderr)
这些文件描述符通常保留给应用程序的标准输入、标准输出和标准错误流。
#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); //awhile (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
#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
#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文件中)
#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
#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 0int i = 0;printf("argc = %d\n", argc);for (i = 0; i < argc; i++){printf("argv[%d] = %s\n", i, argv[i]);}
#endifreturn 0;
}
eg2:某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。
这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。
输入格式:
输入在第一行给出正整数 N,取值在(0,105];随后 N 行,每行给出 1 个人的姓名(由不超过 5 个英文字母组成的字符串)、以及按 yyyy/mm/dd
(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。
输出格式:
在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。
#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;
}