知识点——系统IO
Everything is file in linux :
在Linux下一切皆是文件,其种类具体分为:
普通文件、目录文件、块设备文件(设备文件)、链接文件、管道文件、套接字文件(socket)
对于操作普通文件(text,mp3,JPG)我们可以使用标准IO,标准IO使用标准C库。
对于其他的目录文件跟设备文件我们使用系统IO。
目录:有多个目录项(由文件名和iNode号组成,iNode号包含对应的文件的属性等信息)
opendir(),readdir,closedir();
设备:使用系统IO
一、系统IO具体函数:
open,close ,read, write, lseek,stat, lstat, fstat,unlink,access
1、open函数
man 2 open
#include
#include
#include
int open(const char *pathname, int flags);
pathname:带路径的文件名
flags:标志位
必须包含下列三个之一:
O_RDONLY :只读
O_WRONLY :只写
O_RDWR :可读可写
可选:
O_APPEND:在写的时候把光标定位在文件末尾
O_CREAT:如果文件不存在就创建
O_EXCL:如果文件存在就报错
O_RDONLY|O_CREAT|O_EXCL:保证唯一的新的文件
O_TRUNC:文件已经存在并且是普通文件
并且谁可以写,把文件里的内容清空
返回值:
成功,文件描述符(小的非负的整数)
失败,-1 errno is set appropriately
打开并且创建:(在创建文件的时候赋予文件权限)
int open(const char *pathname, int flags, mode_t mode);
mode:在创建文件的时候,文件的权限 例: 0777
int creat(const char *pathname, mode_t mode);
2、close函数
#include
int close(int fd);
fd:关闭的文件描述符
3、一个系统IO的完整过程
应用层调用系统IO open()函数,返回一个文件描述符FD
系统根据fd在文件描述符表中查询,fd对应了一个iNode的地址。
根据iNode的地址我们可以查询到iNode号,上面有文件的属性,以及在磁盘中保存的地址。
系统MMU根据iNode中文件的信息从虚拟地址转化到物理地址对文件进行操作。
4、read函数
#include
ssize_t read(int fd, void *buf, size_t count);
fd:要读的文件对应的文件描述符
buf:读到的内容存储的地址
count:你需要读的字节数
返回值:
成功:成功读取的字节数
失败:-1 errno 被设置
5、write 函数
#include
ssize_t write(int fd, const void *buf, size_t count)
fd:要写入的文件对应的文件描述符
buf:写到文件中的 内容的 首地址
count:你需要写的字节数
返回值:
成功:成功写入的字节数
失败:-1 errno 被设置
注意:我们进行read,write 的时候文件的光标会自动 偏移。
6、lseek函数
光标重定位:
#include
#include
off_t lseek(int fd, off_t offset, int whence);
功能:把文件fd的光标定位到从whence开始的位置 偏移offset个字节
fd:定位的文件光标
offset: 偏移量
whence:偏移的位置
SEEK_SET 文件起始位置
SEEK_CUR 文件当前光标位置
SEEK_END 相对文件末尾位置
返回值:
成功,返回据文件开头,文件光标的位置
失败,返回-1 errno被设置
问:使用lseek查询文件的大小?
将文件光标定位到文件末尾,返回值就是文件的大小
7、stat函数——查询文件的状态
stat,lstat,fstat。
#include
#include
#include
功能: 从文件fd/path中获取文件的属性 存储到 buf中
int fstat(int fd, struct stat *buf);
fd:查询文件属性用到的文件描述符
int stat(const char *path, struct stat *buf);
path:带路径的文件名
int lstat(const char *path, struct stat *buf);
path:带路径的文件名
buf :存储文件属性 的空间首地址
返回值:
On success, zero is returned. On error, -1 is returned, and errno is
set appropriately.
软连接
lstat :软链接本身的文件属性
stat :软链接指向的文件属性
fstat与stat 除了参数不同别无不同
通过文件描述符fd,或者文件路径查询的信息有(结构体内容):
struct stat
{
dev_t st_dev; /* 设备号*/
ino_t st_ino; /* inode 号 */
mode_t st_mode; /* 保护位 ★ */
nlink_t st_nlink; /* 硬链接数 */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* 设备号 */
off_t st_size; /* 总的大小 (字节数) */
blksize_t st_blksize; /* 文件系统的块大小 ★ */
blkcnt_t st_blocks; /* number of 512B blocks allocated 分配了多少了512个字节的快*/
time_t st_atime; /* 最近访问时间 */
time_t st_mtime; /* time of last modification 修改 */
time_t st_ctime; /* time of last status change */
};
文件类型:st_mode中
S_ISREG(st_mode) is it a regular file? 是0不是普通文件,其他是普通文件
S_ISDIR(st_mode) directory?
S_ISCHR(st_mode) character device?
S_ISBLK(st_mode) block device?
S_ISFIFO(st_mode) FIFO (named pipe)?
S_ISLNK(st_mode) symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(st_mode) socket? (Not in POSIX.1-1996.)
例:
if(S_ISREG(buf.st_mode))
{
printf("It is a regular file\n");
}else
{
printf("It is not a regular file\n");
}
buf.st_mode & S_IFREG: 如果是0 不是普通文件 否则就是普通文件
8、unlink函数——删除一个文件的链接
#include
int unlink(const char *pathname);
删除文件:只能删除一个链接(名字)
返回值:
On success, zero is returned. On error, -1 is returned, and errno is
set appropriately.
所有指向文件的硬链接数为0 并且不能有进程打开该文件
文件彻底删除:磁盘空间可以被重新使用
9、access ——判断文件是否具有某种权限 (文件是否存在)
#include
int access(const char *pathname, int mode);
pathname:检查的文件名
mode:
R_OK,
W_OK,
X_OK.
F_OK:文件存在
返回值:
如果 文件所有的权限都具有 返回0
如果 没有你在mode中指定的权限 返回-1
系统IO注意事项:
一定要注意函数的返回值,特别是read,write。
函数 成功 返回值 失败返回值
open fd 负数错误码
close 0 负数错误码
read 读到字节数 负数错误码
write 写入字节数 负数错误码
lseek 距开头的偏移量 负数错误码
stat 0 负数错误码
unlink 0 -1
access 0 -1