文章目录
Linux文件I/O
主要内容:
- 文件属性
- 无缓冲文件I/O
- 缓冲文件I/O
- 特殊文件
文件属性
主要内容:
- 文件属性
- 文件类型
- 文件存取权限
- 其他属性
1. 文件属性
stat()得到一个与Path所指定的文件有关的信息结构,并保存在第二个参数buf中。
fstat()以将文件打开之后的文件描述符作为参数,功能与stat()函数一致。
lstat()中path指向的文件是一个符号链接,返回的是符号链接有关信息,而不是由该符号链接引用的文件的信息。
buf是一个结构体指针,指向一个结构体,该结构体基本形式如上方 struct stat。
函数成功返回0,失败返回-1。
2. 文件类型
2.1 文件类型
2.2 获取文件类型
3. 文件存取权限
主要内容:
- 文件存取权限
- 修改文件存取权限:命令/程序
- 默认文件存取权限:umask
3.1 文件存取权限
目录文件的权限说明:
读:允许读目录,获得该目录中所有文件名的列表。
在目录中创建一个新文件:必须对该目录具有写许可权和执行许可权。
删除一个文件:要对该目录具有写许可权和执行许可权,与文件本身权限无关。
3.2 改变文件存取权限
要改变一个文件的许可权限,要么进程的有效用户是文件的所有者,要么进程具有超级用户许可权。 可以用 sudo chmod 777 文件。
例:设计一个程序,要求把系统中“/home/mylinux”目录下的myfile文件权限,设置成文件所有者可读可写,其他用户只读权限。
S_IRUSR S_IWUSR S_IXUSR 所属用户的读(4)、写(2)、执行(1)
S_IRGRP S_IWGRP S_IXGRP 与所属用户同组的其他用户的权限
S_IROTH S_IWOTH S_IXOTH 其他用户的权限
chmod()函数用于对指定的文件进行权限修改。
fchmod()函数用于对已打开的文件进行权限修改。
函数成功返回0 失败返回-1
3.3 默认文件存取权限-umask
对于root用户:
新创建的文件(file)的默认权限为 644
新创建的目录(Directory)的默认权限为 755
原因:
普通用户的umask值为002 根用户的umask值为022
在linux中,常用文件权限为666 目录权限为777 文件最终的默认权限是通过和umask值的运算得出来的。
root: File:666-022=644
normal user File:666-002=644
可更改用户的默认umask值:
将umask值写入 /etc/profile 文件中
4.文件的其他属性
主要内容:
- 文件主 chown系列函数
- 文件存取时间 stat函数
- 文件大小 stat函数
4.1 chown/fchown/fchown函数
改变文件所有者:(改变文件的 用户ID 和组ID)
在Linux中,用户按组分类,一个用户可以属于一个或者多个组。每个文件都有一个与之关联的用户ID (UID) 和组ID (GID),即文件的属主和属组。
(函数成功返回0 失败返回-1)
4.2 获取文件存取时间-stat
4.3 获取文件大小-stat
无缓冲文件I/O
主要内容:
- 两种I/O方式
- 文件描述符
- 无缓冲I/O函数:creat,open,close,read/write,lseek,dup/dup2
1. 两种I/O方式
1.1 无缓冲和缓冲I/O
标准IO与文件IO的本质区别是:
- 标准IO函数接口在对文件进行操作时,首先操作缓冲区,等到缓冲区满足一定条件时,然后再去执行系统调用,真正实现对文件的操作。
- 文件IO不操作任何缓冲区,直接执行系统调用,对文件进行操作。
无缓冲(文件IO)是指该IO函数通过系统直接调用实现。
无缓冲的I/O: read,write,open,close等系统函数为无缓冲IO函数
标准(缓冲的)I/O: fgets,fread,fwrite… 缓冲IO是由标准IO库实现
无缓冲IO是对文件描述符操作
带缓冲的标准IO是针对流的
2. 文件描述符
文件描述符:
非负整数
当打开或创建一个新文件时,内核就会向进程返回一个文件描述符。读写文件时,需要把文件描述符作为参数传递给相应的函数。
shell的日常操作中,有三个文件描述符始终是打开的,如下:
POSIX名称是由<unistd.h>所定义的
文件操作的一般步骤:打开—读/写–[lseek]–关闭
3. 无缓冲I/O函数(文件IO)
3.1 错误处理
errno:错误信息对应的一个错误码会被保存在全局变量errno中。
strerror与perror的联系:
两者都是用来输出保存在变量errno中的错误码对应的错误信息。
strerror与perror的区别:
strerror只是把错误码转化为错误信息,需要自己用printf打印,perror则是自己转化+自己打印。
3.2 create函数
创建一个文件或设备。
mode取值如下:
mode & umask
执行creat(“a.txt”,0444)结果为 444
3.3 open函数
打开或创建一个文件或设备,可指定文件打开方式和文件的访问权限。
open返回的是文件描述符表最小的可用整数fd,如果系统中只有1 2 3 则open()函数返回3。
参数flag:指定文件打开方式。
3.4 close函数
用来关闭一个文件描述符。
3.5 read/write函数
3.6 lseek函数
whence有三种模式:
SEEK_SET 定位到文件的开始处
SEEK_CUR 定位到文件的当前位置
SEEK_END 定位到文件的末尾
上面 文件长度为200
3.7 dup/dup2 函数
dup函数返回当前系统可用的最小整数值。
dup2函数返回第一个不小于newfd的整数值。也就是分为两种情况:
①、如果newfd已经打开,则先将其关闭,再复制文件描述符。
②、如果newfd等于oldfd,则dup2返回newfd, 而不关闭它。
3.8 fcntl函数
缓冲文件IO
主要内容:
- 标准IO库
- 文件流
- 标准IO函数
1. 标准IO库
使用标准IO可以减少系统调用的次数,提高系统效率。
2. 文件流
3. 标准I/O函数
3.1 流打开、关闭
打开
r 只读模式:文件必须存在
w 只写模式:1)文件不存在,创建文件 2)文件存在,清空文件
a 追加模式:1)文件不存在,创建文件 2)文件存在,不清空文件,在文件结尾继续写入。
r+ 读写模式:1)文件必须存在
w+ 读写模式 1)文件不存在,创建文件 2)文件存在,清空文件。3)读写指针都在文件头。
a+ 读写模式 1)文件不存在,创建文件 2)文件存在,不清空文件 3)读指针在文件开始位置,写指针在文件末尾位置。
关闭
3.2 流读、写
读取
写入
fgets()函数在读取字符串时,会自动加结束符‘\0’
3.3 流定位
rewind相当于fseek(stream, 0, SEEK_SET)
rewind()函数用于将文件指针重新指向文件的开头,同时清除和文件流相关的错误和eof标记。
3.4 流刷新
刷新全缓冲:
- 缓存区写满
- 强制刷新(fflush)
- 程序正常退出
刷新行缓存:
- 缓冲区写满
- 强制刷新 (fflush)
- 程序正常退出
- 换行符 ‘\n’
exit()可以 _exit()不行
3.5 流缓冲
标准IO提供了三种类型的缓冲:
块(全)缓冲:一般C库函数写入文件是全缓冲的
行缓冲:引用标准交互设备的流 stdin stdout
无缓冲:(没有缓冲区)标准错误流stderr
3.6 流和文件描述符
特殊文件
主要内容:
- 目录文件
- 链接文件
- 设备文件
1. 目录文件
1.1 mkdir/rmdir函数
1.2 读目录
opendir 和 readdir函数都可以完成对目录的操作。
opendir用来打开一个目录,成功则返回一个指向DIR结构的指针,即目录流指针,DIR的本质是一个结构体。
得到指向DIR结构体的指针后,用readdir函数对目录进行读取。
成功则返回一个结构体dirent指针,dirent结构体定义:
文件索引号 文件名称
目录项:
1.3 其他操作函数
telldir() 用于记录一个目录流的位置。
seekdir() 用来设置参数dir目录流读取位置
每个进程都有一个当前工作目录,当前目录是进程的一个属性
进程调用chdir或fchdir函数可以更改当前工作目录
2. 链接文件
2.1 link unlink 函数
link unlink函数分别用来创建和移除硬链接。
unlink() 函数用于移除一个链接(删除一个文件名),若此链接是指向文件的最后一个链接,那么还要移除文件本身。
2.2 symlink readlink函数
symlink() 函数用来创建软链接,移除也用unlink。
readlink() 函数可以获取链接本身的内容。
符号链接存储的内容就是符号链接文件的路径,readlink函数获得的就是链接本身的内容,即其指向的路径名。
3. 设备文件
ssize_t write(int fd, const void *buf, size_t count);
将缓冲区buf这个指针指向的位置的内存中的数据写count个字节写到打开的文件fd中去。