Linux下文件IO

Linux下文件IO-基础

一. 标准IO的介绍
1、文件类型
(1)常规文件 r
(2)目录文件 d
(3)字符设备文件 c
(4)块设备文件 b
(5)管道文件
(6)套接字文件
(7)符号链接文件
  不同的操作系统,支持的文件类型也不相同。

2、标准IO的定义
  由ANSI C标准定义一组函数API,通过缓存机制减少系统调用,实现更高效率。
  系统调用:
   有操作系统情况下,访问硬件,必须通过系统调用。
  缓冲机制:
   标准IO通过缓存机制,减少系统调用,实现更高效率

3、标准-流
(1)FILE:标准IO用结构体类型来存放打开的文件的相关信息.
  标准IO的所有操作都是围绕FILE来进行。
  FILE又被称为流(stream)
  分为文本流和二进制流
(2)流的缓冲类型
  全缓冲:缓存区满或空的时候,才执行操作
  行缓存:当输入输出时,遇到换行符(‘\n’),进行IO操作
  无缓冲:数据直接写入文件
(3)标准IO预定义三个流
  标准输入流:stdin
  标准输出流:stdout
  标准错误流:stderr

二、 流的打开与关闭
1、打开流

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

  成功时返回流指针,错误返回NULL。

2、流的打开方式(r文本流,b二进制流,linux不区别)
(1) r或rb:以只读的方式打开文件,文件必须存在。
(2) r+或r+b:以读写的方式打开文件,文件必须存在
(3) w或wb:以只写的方式打开,文件存在长度清零,不存在创建
(4) w+或w+b:以读写的方式打开,其他同w
(5) a或ab:以只写的方式打开,在文件末尾追加,文件不存在创建
(6) a+或a+b:以读写的方式打开,其他同a

3、fopen新建文件权限
  fopen()创建文件默认 访问权限0666(rw-rw-rw-),受系统掩码影响最终权限是644

4、处理错误信息的函数
  errno存放错号
  perror先输出字符串s ,在输出错误号对应的错误信息
  strerror根据错误号返货对应的错误信息
5、关闭流

int fclose(FILE*stream);

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

三、读写流
1、流的读写方式
(1) 读写一个字符:fgetc()/fputc一次读写一个字符
(2) 读写一行:fgets()/fputs一次读写一行
(3) 读写若干个对象:fread()/fwrite()每次读写相同长度的若干个对象。(推荐)

2、注意事项
(1)fgetc读到文件末尾时,返回EOF (-1)
(2)fgets 成功返回s,到文件末尾或出错,返回NULL
  fgets(char *s ,int size, FILE *stream )
  遇到‘\n’,或读size-1个字符返回,最后追加\0,
(3)fputs 格式:int futs (const char *s,FILE *stream);
  成功时返回输出字符个数,出错时返回EOF
  put输出结果最后追加换行符,fputs不追加

3、按指定对象读写
(1)

size_t fread(void *ptr, size_t size, size_ n, FILE *fp);
size_t fwrite(const void *ptr, size_t size, size_ n, FILE *fp);

  *ptr 存放的缓冲区的地址 size 读写的字符的长度 n读写个数
  FILE 流的地址
  成功时返回读写的对象的个数;出错时返回EOF
  既可以读写文本文件,也可以读写数据文件

4、fgetc()/fputc:可以操作文本文件和数据文件,效率低
  fgets()/fputs:只可以操作文本文件,效率较高
  fread()/fwrite:可以操作文本文件和数据文件,效率也很高(推荐)

四. 刷新流
1、流缓冲区的自动刷新
(1) 缓存区满时,或者出现换行符‘\n’
(2) 流关闭时
(3) 使用fflush函数

2、int fflush(FILE *fp)
(1)成功时返回0,错误返回EOF
(2)将流缓冲区的数据写入实际文件
(3)Linux下只能刷新输出缓冲区

五.定位流
1、

long ftell(FILE *stream);
		long fseek(FILE *stream, long offset, int whence);
		void rewind(FILE *stream);

2、注意
(1)ftell()成功时返回流的当前读写位置,出错返回EOF。
(2)fseek()定位流,设定流当前读写位置。成功返回0,出错返回EOF
  whence参数:SEET_SET/SEEK_CUR/SEEK_END 文件开始位置/文件当前位置/文件结束为止
  offset 偏移量,可正可负
(4) rewind()将流定位到文件的开始位置
(5) 读写流时,当前读写位置自动后移

五. 判断流是否出错和结束
1、int ferror(FILE *stream);检测流是否出错
  int feof(FILE *STREAM);检测流是否到末尾

2、ferror()返回1,表示流出错;否则返回0
  feof()返回1表示文件已经到末尾;否则返回0

六. 格式化输出
1、int printf(const char *fmt,…);
  int fprintf(FILE *stream,const char *fmt,…);输出到指定流里
  int sprint(char *s, const *fmt, …);输出到缓存区里
  成功时返回字符个数;出错时返回EOF
例:输出年-月-日
  fprintf( fp, “%d-%d-%d\n”, year, month, date);
  sprintf( buf, “%d-%d-%d\n”, year, month, date);

2、time()用来获取系统时间(秒数)
  localtime()将系统时间转换成本地时间
  sleep()实现程序睡眠

七、 文件IO
1、标准IO:遵循ANSI C标准,带缓冲机制,通过流FILE表示,
  文件IO:遵循POSIX规范,无缓冲机制,文件描述符表示。可访问各种文件类型
  Linux,标准IO基于文件IO实现

2、文件描述符:一个非负整数。Linux为程序中打开的文件分配一个文件描述符。
  从零开始,依次递增。每个程序文件描述符独立。
  文件IO操作通过文件描述符来完成。
  0,1,2:表示标准输入/输出/错误

3、文件的打开
(1) int open(const char *path, int oflag, …);
(2) 成功时返回文件描述符,出错时返回·EOF,打开使用两个参数,
(3) 只能打开设备文件,
在这里插入图片描述

4、文件的关闭
(1) int close(int fd)
(2) 成功返回0,出错EOF
(3) 程序结束时自动关闭所有打开的文件
(4) 文件关闭后,文件描述符不再代表文件

5、读写文件
(1)#include<unistd.h>
  ssize_t read(int fd, void *buf, size_t count);
(2)功时返回实际读取字节数;出错时返回EOF
(3)读到末尾时返回0
(4) count值一般不超过buf
(5) 写入文件 ssize_t write(int fd, void *buf, size_t count);
(6) 用法与read一致

6、文件定位
(1) off_t lseek(int fd, off_offset, intt whence);
(2) 成功返回当前文件读写位置,出错返回EOF
(3) 参数用法与fseek完全一样

7、读取目录
(1) 打开文件目录
  #include<dirent.h>
  DIR *opendir(const char *name);
(2) DIR用来描述一个打开的目录的结构体类型
(3) 成功时返回目录流指针,出错返回NULL
(4) 读取目录流的内容
  #include<dirent.h>
  struct dirent *readdir(DIR *dirp)
(5) struct dirent描述目录流中的一个目录项的结构体类型
(6) 包含成员插入d_name[256]
(7) 成功时返回目录流dirp中下一个目录项
(8) 出错或到末尾时返回NULL

8、关闭目录
(1) #include<DIR *dirp>
(2) int closedir(DIR *dirp);

9、修改文件访问权限
(1)#include<sys/stat.h>
  int chmod(const char *path, mode_t mode);通过路径
  int fchmod(int fd, mode_t mode);通过文件描述符
(3) 成功时返回0,出错时返回EOF
(4) root和文件所有者能修改文件访问权限
(5) 示例:chmod(“test.txt”, 0666);

10、获取文件属性
(1) #include<sys/star.h>
  int stat(const char *path, struct stat *buf);
  int lstat(const char *path, struct stat *buf);
  int fstat(int fd, strct stat *buf);
(2)成功时返回0,失败返回EOF
(3)mode_t st_mode;类型和访问权限
  uid_t st_uid:所有者id
  uid_t st-gid:用户组id
  off_t st_size: 文件大小
  time_t st_mtime:最后修改时间

八、库概念
1、库是一个二进制文件,包含的代码可被调用
分为标准c库、数学库、线程库
库有源码,可下载编译,也可直接安装二进制包
存放路径在/lib 或/usr/lib

2、Linux下包含静态库和共享库
3、静态库
(1)编译链接时把静态库相关代码复制到可执行文件中
(2)程序中已包含代码,运行时不再需要静态库
程序运行性无需加载库,运行速度更快
占用更多的磁盘和内存空间
静态库升级后,程序要重新编译·

4、静态库的创建
(1)确定库中的函数的功能、接口
(2)编写库原码 hello.c
(3)编译生成目标文件 gcc -c hello.c -Wall
(4)创建静态库 arcrs libhello.a hello.o
(5)查看库中符号信息 nm libhello.a
(6)编写应用程序 test.c
(7)编译test.c 并链接静态库libhello.a
gcc -o test test.c -L. -lhello

八、 共享库
1、共享库特点:编译链接时仅记录了用到共享库哪些符号,不复制共享库中的相关代码。
(1) 程序不包含库中代码,尺寸小
(2) 多个程序可以共享一个库
(3) 程序运行时需要加载库
(4) 库升级方便,无需重新编译链接

2、 共享库的创建
(1)确定共享库中函数的功能、接口
(2)编写库原码hello.c
(3)编译生成目标文件 gcc -c -fPIC hello.c bye.c -Wall
(4)创建共享库common
(5)gcc -shared -o libcommon.so.1 hello.o bye.o (1:版本号)
(6)为共享库文件创建链接文件
  In -s libcommon.so.1 libcommon.so
(7)符号链接文件命名规则 lib<库名>.so
(8)编写库的头文件。在库文件中把所有函数声明一下
(9)编写应用程序并编译 test.c
  gcc -o test test.c -L. -lcommon

3、如何找到共享库
(1)把库拷贝到/usr/lib和/lib目录下
(2)在LD_LIBRARY_PATH环境变量中添加库所在路径
(3)添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值