标准IO与文件IO
关键词: 标准IO 文件IO
IO:input output
主要内容:
- 标准IO
- 文件IO
文档参考:
最新地址: https://taotaodiy-linux.readthedocs.io/en/latest/linux/base/io.html
相关概念
文件:相关数据的集合
文件:存储,一般要非易失介质
文件系统:文件的组织和存储
Linux 文件的分类: 7类文件类型
普通文件 .txt .mp3 -
目录文件 d
字符型设备文件 c
块设备文件 b
链接文件 l
管道文件 p
套接字文件 s
文件操作:操作函数 调用
函数5要素:
1、头文件
2、函数原型
3、参数
4、返回值
5、作用和功能、注意事项
文件受操作系统保护,文件系统
文件IO:文件系统带的操作文件函数,系统调用
1、直接
2种途径:
标准IO:C库所带的,操作文件的一些函数
1、带缓冲的IO,提高效率 刷新(冲洗)缓冲区
3种缓冲刷新机制:
全缓冲
行缓冲 '\n'
不缓冲
2、增强程序的可移植性
终端流:
标准输入流: stdin 行缓冲
标准输出流: stdout 行缓冲
标准错误流: stderr 不缓冲
全局错误变量 errno 记录最近的一次错误
perror(); strerror();
流末尾判定函数:
int feof(FILE *stream);
手动刷新流
fflush()
对于一个流的刷新方法:
1、手动刷新,fflush函数
2、关闭该流,也可以刷新
3、设置流为无缓冲类型 setvbuf 函数
使用"w" 属性创建文件后,文件的属性问题?
0666属性创建 wr-wr-wr-
权限掩码 umask
0666 & ~umask = 最终权限
0666 & ~0077 = 0600
time
localtime
#include <time.h>
time_t time(time_t *tloc);
返回一个秒数从 1970-1-1 0:0:0 到现在的秒数
struct tm *localtime(const time_t *timep);
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
文件空洞:只针对普通文件有效;
移动文件指针,到文件末尾之后,继续往后移动,超过文件末尾,写入数据就会形成文件空洞。
默认填充数值0
st_mode 属性获取文件的类型
001 000 000 110 110 100
其他用户对该文件权限
获取文件的权限
110 110 100
#include <sys/types.h>
#include <pwd.h>
//根据用户uid/gid 获取用户名
struct passwd *getpwuid(uid_t uid);
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
标准I/O
头文件
#include <stdio.h>
打开文件
函数原型
FILE *fopen(const char *path, const char *mode);
FILE *:流,本质是一个结构体指针,指向一个描述打开的文件属性的结构体
文件指针: 记录当前打开的文件 读写的位置,读和写均会移动为文件指针
参数
path:文件的路径
mode:打开模式
"r" :只读方式打开,打开后文件指针在文件开始位置,若文件不存在,出错
"r+":读写方式,继承r的属性
"w" :只写方式打开,清空文件长度,文件不存在就创建
"w+":读写方式,继承w的属性
"a" :追加方式打开,文件指针在文件末尾,只写
"a+":继承"a"的属性,可读可写
文件的读写
函数原型
//读取字符
int fgetc(FILE *stream);
//按行读取字符
char *fgets(char *s, int size, FILE *stream);
//返回值为EOF,说明已读取到文件末尾
//写入字符
int fputc(int c, FILE *stream);
//按行写入字符
int fputs(const char *s, FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
缓存的设置和修改
函数原型
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
文件指针偏移:每次读写文件,文件指针都会发生偏移,使用fseek设置文件指针位置。
函数原型
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream); 获得当前文件指针的位置
参数
stream:流
offset:偏移量
whence:基准点
文件开头 SEEK_SET
当前位置 SEEK_CUR
文件末尾 SEEK_END
文件I/O
打开文件
头文件
#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);
参数
pathname:文件路径
flags:
O_RDONLY, O_WRONLY, O_RDWR 必须选一个,且不能多选
下列选项可以多选:
O_APPEND:追加
O_CREAT:文件不存在就创建
O_EXCL : 文件不存在就报错
O_TRUNC:文件打开时截短文件
mode:用于创建文件
(O_CREAT),指定文件的权限 如:0666 0777
文件的读写
头文件
#include <unistd.h>
函数原型
ssize_t read(int fd, void *buf, size_t count);
参数
fd:要读的文件的文件描述符
buf:容器,存放读到的数据
count:读取的字节数
返回值:ssize_t >0 读到的字节数 == 0 文件末尾 <0 出错
函数原型
ssize_t write(int fd, const void *buf, size_t count);
参数
fd:要写的文件的文件描述符
buf:容器,存放要写入的数据
count:要写入的字节数
ssize_t 实际写入的子节数
目录操作
头文件
#include <sys/types.h>
#include <dirent.h>
函数原型
DIR *opendir(const char *name);
参数和返回值
返回值 DIR 目录流
name:目录路径
struct dirent *readdir(DIR *dirp);
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* not an offset; see NOTES */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all filesystem types */
char d_name[256]; /* filename */
};
该函数可以反复调用,以获取其他文件,直到返回NULL
文件属性
头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
函数原型
参数
pathname:文件名 ./a.txt
buf:文件属性容器
0 成功 -1失败 errno
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
/* Since Linux 2.6, the kernel supports nanosecond
precision for the following timestamp fields.
For the details before Linux 2.6, see NOTES. */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last status change */
#define st_atime st_atim.tv_sec /* Backward compatibility */
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
};
struct timespec {
time_t tv_sec; // seconds
long tv_nsec; // and nanoseconds
};
实例
- Linux命令 copy的实现
- Linux命令 ls -a ls -l的实现 https://taotaodiy-linux.readthedocs.io/en/latest/linux/linux_c/ls.html