IO


IO

标准IO:通过缓冲(缓存)减少系统调用,提高效率

无系统代码直接调用硬件,有系统用系统

流(标准IO)

c标准定义

linux最多能自建1021个流,加上预定义3个流刚好为1024

标准IO预定义3个流

标准输入流stdin / 标准输出流stdout / 标准错误流stderr

文本流

windows:换行符对应‘/r’ ‘/n’

linux:换行符对应‘/n’

二进制流

windows:换行符对应‘/n’

linux:换行符对应‘/n’

缓冲

全缓冲(打开默认文件)

当缓冲区无数据/无空间才执行IO操作

行缓冲

输入输出遇到换行符执行IO操作

流与一个终端关联时是典型的行缓冲

代码中打印信息最好加上换行符

无缓冲

错误信息

打开流

FILE *fopen(const char *path, const char *mode);成功返回流指针,错误返回空

r(文本)/rb(二进制):只读,必须有这个文件

r+(文本)/r+b(二进制):读写,必须有这个文件

w(文本)/wb(二进制):只写,有则清空文件,无则创建

w+(文本)/w+b(二进制):读写,其余同w

a(文本)/ab(二进制):只写,无则创建,有则末尾添加内容

a+(文本)/a+b(二进制):读写,其余同a

fopen创建文件权限为0666(rw-rw-rw-),linux有umask((022)&创建文件的权限)控制权限

用户可以更改umask,但仅影响当前文件

处理错误信息

extern int errno;存放错误号

void perror(const char *s);先输出s,再输出错误号对应错误信息

char *strerror(int errno);根据错误号返回对应错误信息

关闭流

int fclose(FILE *stream);成功返回0,失败返回EOF并设置errno

流关闭会自动刷新缓冲中的数据并释放缓冲区

程序正常终止会自动关闭所有流

关闭流后不可再去访问

读写流(错误或返回为EOF(-1))

fgetc()读一个字符/fputc()写一个字符 效率低

fgets()读一行/fputs()写一行 适用文本文件(二进制文件会出问题)

fread()读若干对象/fwrite()写若干对象 文本文件和二进制文件都适用(推荐使用)

diff -ruN用于比较文本文件

gets()容易造成缓冲区溢出

fgets()读完会在最后添加‘/0’结尾,换行符也会保留,当内容放不下时会读取size-1个字符,最后一位存‘/0’

puts()在输出完后会追加‘/n’,fputs()不会

刷新流

当缓冲区满时系统会自动刷新

int fflush(FILE *fp);成功返回0,失败返回EOF(-1)

linux只能刷新缓冲区,将内容存入文件

定位流

long ftell(FILE *stream);成功返回读写位置,失败返回EOF(-1)

long fseek(FILE *stream, long offset, int whence);成功返回0,失败返回EOF(-1),whence是设置基准点,SEEK_SET开始位置/SEEK_CUR当前位置/SEEK_END结束位置

void rewind(FILE *stream);定位到开始位置

其他

int ferror(FILE *stream);返回1代表流出错

int feof(FILE *stream);返回1代表到文件末尾

格式化输出

int fprintf(FILE *stream, const char *fmt, 。。。);将内容输出到流中

int sprintf(char *s, const char *fmt, 。。。);将内容输出到缓冲区中

sleep函数在unisd.h中,使用该函数需要引用这个文件

使用时间需要精确到秒就需要引入time.h

使用字符串需要引用string.h

%02d代表该数据占两位

文件IO

遵循操作系统标准,无缓冲,通过文件描述符打开文件,使用更加广泛

标准IO基于文件IO

打开文件需要引用fcntl.h

int open(const char *path, int oflag, 。。。);打开文件,成功返回文件描述符,失败返回EOF(-1);仅打开只需两个参数,创建需要用到三个参数

关闭/读取/写入/定位文件需要引用unistd.h

int close(int fd);成功返回0,失败返回EOF(-1)

关闭后文件描述符不再代表文件

ssize_t read(int fd, void *buf, size_t count);成功返回实际读取字节数,失败返回EOF(-1),读到末尾返回0;buf是缓冲区大小,count不能超过buf大小

ssize_t write(int fd, void *buf, size_t count);成功返回实际写入字节数大小,失败返回EOF(-1);buf是缓冲区大小,count不能超过buf大小

off_t Iseek(int fd, off_t offset, intt whence);成功返回当前文件读写位置,失败返回EOF(-1);后两个参数和标准IO的定位函数中一致

访问/关闭目录需要引用dirent.h

DIR *opendir(const char *name);

DIR为描述一个打开的目录文件的结构体类型

成功返回目录流指针,失败返回EOF(-1)

struct dirent *readdir(DIR *dirp);读取目录中的内容

struct dirent用于描述目录流中一个目录项的结构体类型

成功返回目录流dirp中下一个目录项,失败返回NULL

int closedir(DIR *dirp);成功返回0,失败返回EOF(-1)

修改文件访问权限/获取文件属性需要引用sys/stat.h

int chmod(const char *path, mode_t mode);通过路径修改权限

int fchmod(int fd, mode_t mode);通过文件描述符修改权限

成功返回0,失败返回EOF(-1)

root和文件所有者可修改文件访问权限

int stat(const char *path, struct stat *buf);获取符号链接的目标文件的属性

int Istat(const char *path, struct stat *buf);获取符号链接的文件的属性

int fstat(int fd, struct stat *buf);

成功返回0,失败返回EOF(-1)

自编写的库在编译时需要在命令后添加 -L位置 -l函数名

-fPIC文件位置不固定,.a是静态库,.so.X是共享库(动态库)

共享库需要编辑环境中的路径或者在/etc/ld.so.conf.d/下添加一个conf结尾的文件,执行ldconfig刷新


文章作者: hhs1231
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 hhs1231 !
评论
  目录