1. 文件基础

  1. 概念:一组相关数据的有序集合

  1. 文件类型:

  1. 常规文件r

  1. 目录文件d

  1. 字符串设备文件c

  1. 块设备文件 b

  1. 管道文件p

  1. 套接字文件s

  1. 符号链接文件l

  1. 系统调用和库函数

内核显卡驱动

把数据扔给内核,内核提供接口

  1. 标准I/O-流

  1. FILE

  1. 标准io用一个结构体类型来存放打开的文件相关信息

  1. 标准I/O的所有操作都是围绕FILE来进行

  1. 流(stream)

  1. FILE又被称为流(stream)

  1. 文本流/二进制流

  1. windows

  1. 二进制流:换行符<- -> '\n'

  1. 文本流:换行符 <- -> '\r' '\n'

  1. linux

  1. 换行符<- -> '\n'

  1. 流的缓冲类型

  1. 全缓冲

  1. 当流的缓冲区无数据或无空间时才执行实际I/O操作

  1. 行缓冲

  1. 当在输入和输出中遇到换行符('\n')时进行I/O操作

  1. 当流和一个终端关联时,典型的行缓冲

  1. 无缓冲

  1. 数据直接写入文件,流不进行缓冲

  1. 标准I/O-stdin,stdout,stderr

  1. 标准I/O预定义3个流,程序运行时自动打开

  1. 标准输入流 0 STDIN_FILENO stdin(linux系统定义好的结构体)

  1. 标准输出流 1 STDOUT_FILENO stdout

  1. 标准错误流 2 STDERR_FILENO stderr

  1. stdin/stdout默认是行缓冲

  1. 缓冲区实验(4097可以打印,因为超过缓冲区)printf遇到\n结束

  1. 文件的打开和关闭

  1. 打开就是占用资源

  1. 关闭就是释放资源

  1. 下列函数可用于打开一个标准I/O流:

FILE *fopen (const char *path,const char *mode);

成功时返回流指针,出错时返回NULL;所以使用fopen函数必须判断是否是空的

d.关闭文件 int fclose(FILE *stream);

fclose()调用成功返回0,失败返回EOF,并设置errno

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

当一个程序正常终止时,所有打开的流都会被关闭

流一旦关闭后就不能执行任何操作

fclose()函数入参stream必须保证非空,否则出现段错误。

  1. 标准I/O读写

  1. 读写单个字符

  1. 字符输入:

  1. int fgetc(FILE *stream);

  1. int getc(FILE *stream); // 宏

  1. int getchar(void);

  1. 成功返回读取的字符,若到文件末尾或出错时返回EOF(-1)

  1. getchar()等同于fgetc(stdin)

  1. getc和fgetc区别是一个是宏一个是函数

  1. 注意:函数返回值是int类型而不是char类型,主要是为了扩展返回值的范围。

  1. 注意:stdin也是FILE*的指针,是系统定义好的,指向的是标准输入(键盘输入)

  1. 打开文件后读取,是从文件开头开始读。读完一个后,读写指针会后移。读写注意文件位置

  1. 字符输出:

  1. int fputc(int c, FILE *stream)

  1. int putc(int c, FILE *stream);

  1. int putchar(int c);

  1. 成功时返回写入的字符,出错时返回EOF

  1. putchar(c)等同于fputc(c, stdout)

  1. 注意:返回和输入都是int类型

  1. 遇到Bad file descriptor 一般是读写模式用错

  1. 按行读写文件

  1. 按行输入

  1. char *gets(char *s);//读取标准输入到缓冲区s

  1. char *fgets(char *s, int size, FILE *stream);//遇到'\n'或已输入size-1个字符时返回,总时包含'\0'

  1. 成功时返回s,到文件末尾出错时返回NULL

  1. 注意事项:gets函数已经被淘汰,因为会导致缓冲区溢出,fgets函数第二个参数,输入的数据超出size,size-1个字符会保存到缓冲区,最后添加'\0',如果输入数据少于size-1,后面会添加换行符

  1. 按行输出

  1. int puts(const char *s);

  1. int fputs(const char *s, FILE *stream);

  1. 成功时返回非负整数,出错时返回EOF

  1. puts将缓冲区s中的字符串输出到stdout,并追加\n

  1. fputs将缓冲区s中的字符串输出到stream,不追加\n

  1. 二进制读写

  1. 文本文件和二进制的区别:存储格式不同(文本文件只能存储文本),除了文本文件都是二进制文件

  1. 计算机内码概念

  1. 下列函数用来从流中读写若干个对象

  1. size_t fread(void *ptr, size_t size, size_t n, FILE *fp);//ptr读的内容,size一次读取的块大小,n是读取的个数,fp要读的文件指针

  1. size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);// 同读,fp要写的文件指针

  1. 成功返回读写的对象个数,出错时返回EOF。既可以读写文本文件,也可以读写数据文件,效率高。

  1. 注意事项:文件写完后,文件指针指向文件末尾,如果这时候读,读不出来内容。

  1. 解决办法:移动指针到文件头(后面讲解):关闭文件,重新打开

  1. 文件流的刷新和定位

  1. 刷新流int fflush(FILE *fp);

  1. 成功时返回0,出错时返回EOF

  1. 将流缓冲区中的数据写入实际的文件

  1. linux下只能刷新输出缓冲区,输入缓冲区丢弃

  1. 如果输出到屏幕使用fflush(stdout)/fflush(fp)

  1. 定位流-ftell/fseek/rewind

  1. long ftell(FILE *stream);

  1. 成功时返回流当前读写位置,出错时返回EOF

  1. long fseek(FILE *stream,long offset, int whence);

  1. 定位一个流,成功时返回0,出错时返回EOF

  1. void rewind(FILE *stream);

  1. whence参数:SEEK_SET/SEEK_CUR/SEEK_END(这三个函数只适用2G以下的文件)

  1. SEEK_SET从据头文件开头offset位移量为新的读写位置

  1. SEEK_CUR以目前的读写位置往后增加offset个位移量

  1. SEEK_END将读写位置指向文件尾后再增加offset个位移量

  1. offset参数:偏移量,可正可负

  1. 打开a模式fseek无效,rewind(fp)相当于fseek(fp,0,SEEK_SET);

  1. rewind()将流定位到文件开始位置

  1. 读写流时,当前读写位置自动后移

  1. 示例一(在文件末尾追加字符't')

  1. FILE *fp = fopen("test.txt", "r+");

  1. fseek(fp, 0, SEEK_END);

  1. fputs('t', fp);

  1. 格式化输入和输出

  1. sprintf

  1. int sprintf(char *s, const char *fmt,...);

  1. fprintf

  1. int fprintf(FILE *stream, const char *fmt,...);

  1. 成功时返回输出的字符个数,出错时返回EOF,使用起来很方便,强烈推荐

  1. fscanf

  1. int fscanf(FILE *stream, const char *format, ...);

  1. sscanf

  1. int sscanf(const char *str, const char * format,...);

  1. 什么是文件I/O?

  1. posix(可移植操作系统接口)定义的一组函数

  1. 文件IO不提供缓存冲机制,每次读写操作都引起系统调用

  1. 核心概念是文件描述符

  1. 每个打开的文件都对应一个文件描述符。

  1. 文件描述符是一个非负整数。Linux为程序中每个打开的文件分配一个文件描述符。(是0-1023的数字,表示文件)

  1. 文件描述符从0开始分配,依次递增

  1. 文件IO操作通过文件描述符来完成

  1. 0:标准输入 stdin 1:标准输出 stdout 2:标准错误 stderr

  1. 访问各种类型文件,Linux下,标准IO基于文件IO实现

标准IO

文件IO(低级IO)

打开

fopen,freopen,fdopen

open

关闭

fclose

close

getc,fgetc,ggetchar,fgets,gets,fread

read

putc,fputc,putchar,fputs,puts,fwrite

write

  1. open函数用来创建或打开一个文件

  1. #include<fcntl.h>

  1. int open(const char *pathname, int flags);//不创建文件

  1. int open(const char *pathname,int flags, mode_t mode);//创建文件,但是不能创建设备文件

  1. pathname文件名,可包括路径名

  1. flags:

  1. O_RDONLY:只读方式打开文件

  1. O_WRONLY:可写方式打开文件

  1. O_RDWR:读写方式打开文件

  1. O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三的参数为其设置权限

  1. O_EXECL:如果用O_CREATE时文件存在,则返回错误信息。这一参数可测试文件是否存在。

  1. O_NOCTTY:使用本参数时,如文件为终端,那么终端不可作为调用open()系统调用的哪个进程控制终端

  1. O_TRUNC:如果文件已经存在,那么打开文件时先删除文件中的原有数据

  1. O_APPEND:以添加方式打开文件,所以对文件的些操作都在文件的末尾进行

r

O_RDONLY

r+

O_RDWR

w

O_WRONLY|O_CREAT|O_TRUNO,0664

w+

O_RDWR|O_CREAT|O_TRUNC,0664

a

O_WRONLY|O_CREAT|O_APPEND,0664

a+

O_RDWR|O_CREAT|O_APPEND,0664

  1. mode:被打开文件的存取权限,为8进制表示法。

  1. 成功时返回文件描述符,出错时返回EOF

  1. 打开文件时使用两个参数

  1. 创建文件时第三个参数指定新文件的权限,(只有在建立新文件时有效)此外真正建文件时的权限会受到umask值影响,实际权限是mode-umask

  1. umask:用来设定文件或目录的初始权限

  1. 文件和目录的真正初始权限

  1. 文件或目录的初始权限=文件或目录的最大默认权限-umask

  1. 可以打开设备文件,但是不能创建设备文件(创建设备文件mknode驱动部分会讲)

  1. close函数用来关闭一个打开的文件:

  1. #include<unistd.h>

  1. int close(int fd);

  1. 成功时返回0;出错时返回EOF(-1)

  1. 程序结束时自动关闭所有打开的文件

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

  1. 文件IO的读写定位

  1. 读取文件

  1. #include<unistd.h>

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

  1. 成功时返回实际读取的字节数,出错时返回EOF

  1. 读到文件末尾时返回0

  1. buf是接收数据的缓冲区

  1. count不应超过buf大小

  1. 写入文件

  1. #include <unistd.h>

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

  1. 成功时返回实际读取的字节数,出错时返回EOF

  1. buf是接收数据的缓冲区

  1. count不应超过buf大小

  1. 定位文件

  1. #include<unistd.h>

  1. off_t lseek(int fd, off_t offset, intt whence);

  1. 成功时返回当前文件读写位置;出错时返回EOF

  1. 参数offset和whence同fseek相同

  1. 目录操作和库的使用

  1. 访问目录

  1. opendir函数用来打开一个目录文件

  1. #include<dirent.h>

  1. DIR *opendir(const char *name);

  1. DIR *fdopendir(int fd);使用文件描述符,要配合open函数使用

  1. DIR是用来描述一个打开的目录文件的结构体类型

  1. 成功时返回目录流指针,出错时返回NULL

  1. readdir函数用来读取目录流中的内容

  1. #include<dirent.h>

  1. struct dirent *readdir(DIR *dirp);

  1. struct dirent是用来描述目录流中一个目录项的结构体类型

  1. 包含成员char d_name[256] 参考帮助文档

  1. 成功时返回目录流dirp中下一个目录项

  1. 出错或到末尾时返回NULL

  1. closefir函数用来关闭一个目录文件

  1. #include<dirent.h>

  1. int closedir(DIR *dirp);

  1. 成功时返回0,出错时返回EOF

  1. 修改文件访问权限-chomod/fchmod

  1. #include<sys/stat.h>

  1. int chmod(const char *path, mode_t mode);

  1. int fchmod(int fd, mode_t mode);

  1. 成功时返回0,出错返回EOF

  1. root和文件所有者能修改文件的访问权限:chmod("test.txt", 0666);

  1. 获取文件属性-stat/lstat/fstat

  1. #include<sys/stat.h>

  1. int stat(const char *path,struct stat*buf);

  1. int lstat(const char *path, struct stat *buf);

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

  1. 成功时返回0,出错时返回eof

  1. 如果path是符合链接stat获取的是目标文件的属性,而lstat获取的是连接文件的属性

  1. struct stat结构体s是存放文件属性的结构体类型

  1. mode_t st_mode; 类型和访问权限

  1. uid_t st_uid; 所有者id

  1. uid_t st_gid;用户组id

  1. off_t st_size; 文件大小

  1. time_t st_mtime;最后修改时间

  1. struct stat{

dev_t st_dev;//文件的设备编号

ino_t st_ino; // 节点

mode_t st_mode; //文件的类型和存取的权限

nlink_t st_nlink; // 连到该文件的硬链接数目,刚建立的文件值为1

uid_t st_uid; // 用户id

gid_t st_gid; // 组ID

dev_t st_rdev; // (设备类型)若此文件为设备文件,则为其设备编号

off_t st_size; // 文件字节数(文件大小)

unsigned long st_blksize; // 块大小(文件系统的I/O缓冲区大小)

unsigned long st_blocks; // 块数

time_t st_atime;//最后一次访问时间

time_t st_mtime; //最后一次修改时间

time_t st_ctime; // 最后一次改变时间(指属性)

}

  1. 文件类型-通过系统提供的宏判断文件类型:

  1. S_IFMT 0170000 文件类型的位遮罩

  1. S_ISREG(st_mode) 0100000 是否常规文件

  1. S_ISDIR(st_mode) 0040000 是否目录

  1. S_ISCHR(st_mode) 0020000 是否字符设备

  1. S_ISBLK(st_mode) 0060000 是否块设备

  1. S_ISFIFO(st_mode) 0010000 是否FIFO文件

  1. S_ISLNK(st_mode) 0120000 是否链接文件

  1. S_ISSOCK(st_mode) 0140000 是否SOCKET文件

  1. 文件访问权限-通过系统提供的宏来获取文件访问权限

  1. S_IRUSR 00400 bit:8 所有者有读权限

  1. S_IWUSR 00200 7 所有者拥有写权限

  1. S_IXUSR 00100 6 所有者拥有执行权限

  1. S_IRGRP 00040 5 群组拥有读权限

  1. S_IWGRP 00020 4 群组拥有写权限

  1. S_IXGRP 00010 3 群组拥有执行权限

  1. S_IROTH 00004 2 其他用户拥有读权限

  1. S_IWOTH 00002 1 其他用户拥有写权限

  1. S_IXOTH 00001 0 其他用户拥有执行权限

  1. 静态库和动态库使用

  1. 库的概念

  1. 库是一个二进制文件,包含的代码可被程序调用:

  1. 标准c库

  1. 数学库

  1. 线程库...

  1. 库有源码,可下载后编译;也可以直接安装二进制包

  1. /lib

  1. /usr/lib

  1. 库是事先编译好的,可以复用的代码。在os上运行的程序基本上都要使用库。使用库 提高开发效率。Windows和Linux下库文件格式不兼容。Linux下包含静态库和共享库。

  1. 静态库特点

  1. 编译(链接)时把静态库中相关代码复制到可执行文件中

  1. 程序中已经包含代码,运行时不再需要静态库。

  1. 程序运行时无需加载库,运行速度更快

  1. 占用更多磁盘和内存空间。静态库升级后

  1. 程序需要重新编译链接

  1. 静态库创建

  1. 命令:ar rsv libhello.a hello.o (假如hello.o文件) /// 用lib开头,静态库是.a

  1. ar参数:

  1. c禁止在创建库时产生的正常消息

  1. r 如果指定的文件已经存在于库中,则替换它

  1. s 无论ar命令是否修改了库内容都强制重新生成库符号表

  1. v将建立新库的详细的逐个文件的描述写至标准输出

  1. q将指定的文件添加到库的末尾

  1. t将库的目录写至标准输出

  1. 步骤:

  1. 编写库文件代码,编译为.o文件

  1. ar 命令 libxxx.a xxx.o

  1. 静态库要以lib开头,后缀名为.a

  1. 没有main函数的.c文件不能生成可执行文件

  1. 链接静态库

  1. 编译test.c并链接静态库libhello.a

  1. gcc -o test test.c -L. -lhello(不用libhello直接小写L+hello)

  1. ./test

  1. 动态库(共享库)特点

  1. 编译(链接)时仅记录用到哪个共享库中的哪个符号,不复制共享库中相关代码

  1. 程序中不包含库中代码,尺寸小

  1. 多个程序可共享同一个库

  1. 程序运行时需要加载库

  1. 库加载方便,无需重新编译程序

  1. 使用更加广泛

  1. 动态库生成步骤

  1. 生成位置无关的代码目标文件

  1. 使用gcc -c -fPID xxx.c xxx.c ....

  1. 生成动态库

  1. gcc -shared -o libxxx.so xxx.o xxx.o ...

  1. 链接动态库

  1. gcc -o test test.c -L. -lxxxx

  1. 如何找到共享库

  1. 为了让系统能找到要加载的共享库,有三种方法:

  1. 把库拷贝到/usr/lib和/lib下

  1. 在LD_LIBARY_PATH环境变量中添加库所在路径

  1. 添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新

  1. ~/.bashrc文件里面

  1. source ~/.bashrc生效

  1. ldd查看可执行文件的动态库

10.标准IO和文件IO相关推荐

  1. LinuxC—标准IO与文件IO学习笔记

    标准IO与文件IO 1 概述 stdio 标准IO(优先使用) sysio 系统调用IO(文件IO) sysio是直接实现用户态切换内核态,sysio和平台是有关系的,比如windows和linux, ...

  2. IO进程——系统IO与文件IO

    IO进程--系统IO与文件IO 在应用开发过程中会经常需要访问文件.Linux下读写文件的方式有两大类:标准IO和文件IO.本次就来讲一讲文件IO和标准IO,以及两者的区别. 一.文件IO 在Linu ...

  3. step4 . day1标准IO和文件IO

    标准IO:ANSI C中定义的一系列用于对IO操作的函数,(只能访问普通文件) 知识点:流指针:文件的操作,标准IO通常通过一个FILE的结构体,称这个结构体为流,他的指针称为流指针(系统自动打开的流 ...

  4. 文件IO——标准IO和文件IO的区别

    文件IO和标准IO主要的区别在于有无缓冲区,标准IO在进行系统调用操作时,会先操作缓冲区,而文件IO则直接进行系统调用.(常见的系统调用write.read.printf等) 标准IO:在操作文件的时 ...

  5. c语言中的标准IO以及文件IO

    1.标准IO: (1)标准IO是c语言标准提供的一系列进行输入输出的函数 (2)标准IO具有缓冲区 (3)标准IO是在系统调用之上构建的 2.缓冲区 缓冲区是系统在内存中为正在使用的文件自动开辟的一片 ...

  6. 《Linux操作系统 - 高级编程》第一部分 标准IO及文件IO(第2章 标准IO)

    2.1 Linux I/O概述 2.1.1文件I/O和标准I/O的概念 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的 ...

  7. 漫谈linux文件io,Linux文件IO与通用块层的请求合并

    本文参考https://mp.weixin.qq.com/s/Imt4BW-zoHPpcOpcKZs_AQ, 公众号"Linux阅码场" 请求合并就是将进程内或者进程间产生的在物理 ...

  8. step4 . day2标准IO和文件IO 小测试demo

    为了熟练一下各种函数,练习两个小demo,练习新的就是记住函数名字和功能就行,剩下的细节查man手册(多年学的英语单词终于用到实处了,背单词真有用!!) 1.行数查询 #include <std ...

  9. Linux文件 IO 和标准 IO简介

    文件 IO 是 Linux 系统提供的接口, 针对文件和磁盘进行操作, 不带缓存机制: 标准 IO 是 C 语言函数库里的标准 I/O 模型, 在 stdio.h 中定义, 通过缓冲区操作文件, 带缓 ...

最新文章

  1. ELK不香了!我用Graylog
  2. 【 MATLAB 】MATLAB 实现模拟信号采样后的重建(一)
  3. linux有关Block的知识
  4. Ubuntu下千千静听Audacious的安装步骤详解
  5. K12教育整体业务流程+涉及各类产品分析
  6. java的编译代码混淆
  7. VS2008非托管c++访问webservice服务(以WeatherWS 天气服务 为例)
  8. 2017.9.28 产品加工 思考记录
  9. Codeforces 解题报告索引
  10. 安装完VS2010之后再安装VS2012以后,发现VS工程编译出现--fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  11. SNMP 模拟器 vxsnmpsimulator 使用方法
  12. 数据分析与预测课程设计
  13. Win10注册.bat或.exe成为系统服务(NSSM)
  14. 一张图看懂零维到十维空间
  15. nginx 504 Gateway Time-out错误解决办法
  16. Java知识点(三)
  17. BibTex使用笔记
  18. 判断二极管导通例题_通信电源 | 1个二极管是如何改变电流的?
  19. 【java逻辑运算】java逻辑运算符的使用与计算
  20. 优化算法——模拟退火算法

热门文章

  1. 爱奇艺下载的QSV格式视频如何转换成MP3音频
  2. 今日简报 每日精选12条新闻简报 每天一分钟 知晓天下事 2月23日
  3. 微信公众号开发小坑:确认访问的微信是否为已关注公众号,秘钥使用全局access_token不能使用局部变量access_token
  4. php程序root权限,获取root权限 php执行shell
  5. SpringBoot+Mybatis-Plus+Thymeleaf+Bootstrap分页查询(前后端完整版开源学习)图书管理系统
  6. 谷歌浏览器插件:修改接口响应、重定向以及拦截url
  7. js是滚动条滑到固定位置_js滚动到指定位置
  8. 网站改版是不是要有服务器,听说现在天堂又要改版了,还要开新服务器了,就是不知道什么时候能搞? 爱问知识人...
  9. IP 核之RAM实验
  10. U盘中文件无法删除,删除后一刷新又出现,并提示“文件或目录损坏且无法读取”的解决方法