【1】文件IO
必须使用操作系统提供输入输出函数来实现文件的读写、定位操作,不能在其他的系统中使用。
文件描述符: 实际上是一个非负的整形数据,文件指针是文件描述的一个软连接
最大数据:0 ~ 1023 打开得文件袋描述符的个数是1024个
无缓冲:
文件IO对比标准IO:标准IO通过对常规文件进行操作,文件IO通常对特殊文件记性操作;文件IO也可以对常规文件进行读写、定位操作。
1、打开或者创建
open(pathname ,flags, mode)//打开
umask就是用来修改文件权限,
在创建文件时,可以通过umask对文件权限进行修改,修改方式
mode & ~umask
(1)先查看umask是多少?
(2)设置umask值是多少?
(3)创建文件,然后通过ll filename 查看文件的全限
注意:编程umask函数来修改
pathname 指定的文件名字
flags
读写操作方式:
O_RDONLY 读操作
O_WRONLY 写操作
O_RDWR 读写操作
O_CREAT 创建文件
O_EXCL 表示文件已经存在,而又重复创建一次,open函数会返回错误,
返回文件已经存在的错误,对错误做处理之后,直接打开文件就可以
O_APPEND 从文件末尾位置追加写入
open(argv[1], O_RDONLY)
open(argv[1], O_WRONLY | O_CREAT | O_TRUNC , 0666)
open(argv[1], O_WRONLY | O_CREAT | O_APPEND, 0666)
文件IO和标准IO的等价形式:
r <--> O_RDONLY
r+ <--> O_RDWR
w <--> O_WRONLY | O_CREAT | O_TRUNC
w+ <--> O_RDWR | O_CREAT | O_TRUNC
a <--> O_WRONLY | O_CREAT | O_APPEND
a+ <--> O_RDWR | O_CREAT | O_APPEND
2、读写、定位
read、write、lseek
ssize_t read(int fd, void *buf, size_t count);
功能: 从指定的文件中读取数据
参数:
fd 指定的文件,通过open函数返回的文件描述符
buf 从文件当中读取数据存放到用户程序空间当中,事先定义数组或者
变量传递着地址
count 要求从文件中读取多少字节的数据
返回值:
成功 返回实际读取的字节数
失败 -1
从指定位置读取数据时如果指定位置没有数据read,就会产生阻塞
ssize_t write(int fd, const void *buf, size_t count);
功能: 往指定的文件中写入数据
参数:
fd 指定的文件,通过open函数返回的文件描述符
buf 从用户程序空间当中读取数据写入到文件,事先定义数组或者
变量传递着地址
count 要求往文件中写入多少字节的数据
返回值:
成功 返回实际写入的字节数
失败 -1
off_t lseek(int fd, off_t offset, int whence);
功能: 重新定位文件位置指针
参数:
fd open函数打开的文件
whence 基准点
SEEK_SET
SEEK_CUR
SEEK_END
offset 正数往文件的末尾位置偏移,负数往文件的开头位置偏移,0表示不移动。
lseek(fd, 5, SEEK_SET);
lseek(fd, 0, SEEK_SET);
lseek(fd, 5, SEEK_CUR);
lseek(fd, -5, SEEK_CUR);
lseek(fd, 0, SEEK_CUR);
lseek(fd, 5, SEEK_END);
lseek(fd, -5, SEEK_END);
lseek(fd, 0, SEEK_END);
3、关闭
close
od -c filename 可以查看文件中的数据信息,显示到终端上
【2】获取文件属性信息stat
int stat(const char *path, struct stat *buf);
功能:获取文件属性信息函数
参数:
path 表示要获取哪个文件的属性信息
buf 需要事先定义一个结构体变量,用来存储path指向的那个文件袋额属性信息。
返回值:
成功 0
失败 -1
【3】 目录
打开目录操作
opendir
#include <dirent.h>
DIR *opendir(const char *name);
功能:打开目录
参数:
name 目录的名字
返回值:
成功 DIR*
失败 NULL
读取目录信息
struct dirent *readdir(DIR *dirp);
struct dirent {
ino_t d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file; not supported
by all file system types */
char d_name[256]; /* filename 文件的名字*/
};
功能: 读取目录中的文件信息
参数:
dirp 你要读取的目录是哪一个? 有opendir返回
返回值:
成功: struct dirent *(事先顶一个变量接受文件的信息)
失败 NULL(做判断,是否到大文件结束或者读取失败)
关闭目录
closedir(DIR*)
【4】库
(1)什么是库?
库其实就是一个经过编译之后的二进制文件,可以被执行,但是不能单独执行,库中存放的函数功能的实现,供用户程序调用,然后把程序中调用函数从库中添加你的可执行程序中。
(2)库的分类
静态库:
编译 可执行程序的时候,把库中的代码添加可执行程序中,添加完之后,跟静态库没有任何的关系,文件的大小会变大。执行效率会更高一些
动态库:(共享库)
可以被多个程序(进程)共同访问的库,可执行运行起来之后,去内存中,找到共享访问共享库中的代码只是在运行访问,程序接续不在访问文件的大小没有变大。相对来说效率更低一些。
(3)库的制作流程
静态库
a、确定函数的功能,添加文件file.c中, 把文件制作成库
b、库的组成部分是由.o文件组成,生成.o文件
c、把.o文件制作成库
静态库是.a为后缀。以lib开头, 两者之间加上库的名字 libadd.a
ar -crs libmymath.a mymath.o
c 创建
r 插入
s 索引
库的名字自己定义
d、编译程序访问库
指定库的路径 -L(表示指定路径) .(表示当前目录)
指定库文件的名字 -l(指定文件的名字) add
gcc main.c -o main —L . -ladd
共享库:
共享库是.so为后缀。以lib开头, 两者之间加上库的名字 libadd.so
a、gcc -fPIC -c mamath.c -o mymath.o
-fPIC指定位置无关代码(只要系统把共享库加载到内存合适的空间中就可以)
b、gcc -shared mymath.o -o libmymath.so
-shared 共享(可以被多个程序调用)
c、gcc main.c -o main -L . -lmymath
执行可执行程序,你会发现不能执行,引文系统找不到库所在的路径,用户必须添加路径
d1、cp libmymath.so /lib或者/usr/lib
d2、设置共享库的环境变量LD_LIBRARY_PATH(绝对路径)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/linux/io-day1/io-day2/dymaic
d3、添加配置文件在配置文件中,生成一个.conf的文件,在文件中添加共享库的绝对路径
cd /etc/ld.so.conf.d
sudo vi mymath.conf
在文件中添加/home/linux/io-day1/io-day2/dymaic就可以。
【注意】
添加完之后,必须对配置文件进行刷新操作
使用ldconfig
删除/etc/ld.so.conf.d/libmymath.so时,必须必须刷新配置文件
使用ldconfig