linux 文件IO

大多数Linux文件IO只需要用到5个函数:open,read,write,lseek以及close

open

函数原型:

1
int open(const str * pathname, int oflag, [..., mode_t mode])

功能:打开文件 返回值:成功则返回文件描述符,出错返回-1
参数:
pathname: 打开或创建的文件的全路径名
oflag:
O_RDONLY:只读打开
O_WRONLY:只写打开
O_RDWR:读写打开
O_APPEND:追加到文件尾
O_CREAT: 若文件不存在则创建
O_EXCL: 如果同时指定O_CREAT,而该文件又是存在的,报错;
也可以测试一个文件是否存在,不存在则创建。
O_TRUNC: 如果次文件存在,而且为读写或只写成功打开,则将其长度截短为0
O_SYNC: 使每次write都等到物理IO操作完成
mode:对于open函数而言,仅当创建新文件时才使用第三个参数,表示新建文件的权限设置

read

函数原型:

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

功能:从打开的文件中读取数据。
返回值:实际读到的字节数;已读到文件尾返回0,出错的话返回-1
ssize_t是系统头文件中用typedef定义的数据类型相当于signed int
参数:
fd:要读取的文件的描述符
buf:得到的数据在内存中的位置的首地址
count:期望本次能读取到的最大字节数。
size_t是系统头文件中用typedef定义的数据类型,相当于unsigned int

write

函数原型:

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

功能:向打开的文件写数据
返回值:写入成功返回实际写入的字节数,出错返回-1
参数:
fd:要写入文件的文件描述符
buf:要写入文件的数据在内存中存放位置的首地址
count:期望写入的数据的最大字节数

close

函数原型

1
int close(int filedes)

功能:关闭一个打开的文件
参数:需要关闭文件的文件描述符

lseek

每个打开的文件都有一个“当前文件偏移量”,是一个非负整数,用以度量从文件开始处计算的字节数。
通常,读写操作都是从当前文件偏移量处开始,并使偏移量增加所读或写的字节数。
默认情况下,你打开一个文件时(open),除非指定O_APPEND参数,不然位移量被设为0。

1
off_t lseek(int filesdes, off_t offset, int whence)

功能:设置文件内容读写位置
返回值:成功返回新的文件位移,出错返回-1;
whence:
SEEK_SET, 位移量为距文件开始处offset个字节
SEEK_CUR, 位移量为当前值加offset。offset可为正或负
SEEK_END, 位移量为文件长度加offset。offset可为正或负

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char * argv[])
{

int fd;
char buf[100];
if ((fd = open(argv[1], O_RDONLY)) < 0) {
perror("open");
exit(-1);
}
read(fd, buf, 1);
write(STDOUT_FILENO, buf, 1);
lseek(fd, 2, SEEK_CUR);

read(fd, buf, 1);
write(STDOUT_FILENO, buf, 1);
lseek(fd, -1, SEEK_END);

read(fd, buf, 1);
write(STDOUT_FILENO, buf, 1);
lseek(fd, 0, SEEK_SET);

read(fd, buf, 1);
write(STDOUT_FILENO, buf, 1);
close(fd);
printf("\n");
return 0;
}

stat的使用

1.stat 的基本使用
系统调用stat的作用是获取文件的各个属性。
函数原型:

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

功能:查看文件或目录属性。将参数path所指的文件的属性,复制到参数buf所指的结构中
参数:
path:要查看属性的文件或目录的全路径名称。
buf:指向用于存放属性的结构体。
stat成功调用后,buf的各个字段将存放各个属性。
返回值:成功返回0;失败返回-1
struct stat是系统头文件中定义的结构体,定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* file type and mode */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for filesystem I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */

struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last modification */
struct timespec st_ctim; /* time of last status change */
}

注意:lstat函数用法与stat函数基本一样,但当查询的文件是符号链接时,
lstat会返回符号链接的基本信息,但stat会返回符号链接引用的文件信息

2.文件类型的判定

1
2
3
4
5
6
7
S_ISREG()	普通文件
S_ISDIR() 目录文件
S_ISCHR() 字符设备文件
S_ISBLK() 块设备文件
S_ISFIFO() 有名管道文件
S_ISLNK() 软连接(符号链接)文件
S_ISSOCK() 套接字文件

3.文件权限的判定
文件类型与许可设定被一起编码在st_mode字段中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
S_ISUID	执行时,设置用户ID
S_ISGID 执行时,设置组ID
S_ISVTX 保存正文
S_IRWXU 拥有者的读、写和执行权限
S_IRUSR 拥有者的读权限
S_IWUSR 拥有者的写权限
S_IXUSR 拥有者的执行权限
S_IRWXG 用户组的读、写和执行权限
S_IRGRP 用户组的读权限
S_IWGRP 用户组的写权限
S_IXGRP 用户组的执行权限
S_IRWXO 其它读、写、执行权限
S_IROTH 其它读权限
S_IWOTH 其它写权限
S_IXOTH 其它执行权限

目录操作

1.打开目录
函数原型:

1
DIR * opendir(const char * name)

功能:打开参数name指定的目录,并返回DIR *形态的目录流
返回值:成功返回目录流;失败返回NULL
2.读取目录
函数原型:

1
struct dirent * readdir(DIR * dir)

功能:返回参数dir目录流的下一个子条目(子目录或子文件)
返回值:成功返回结构体指向的指针,错误或以读完目录,返回NULL
dirent结构体原型:

1
2
3
4
5
6
7
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256]; //存放子条目的名称
};

3.关闭目录
函数原型:

1
int closedir(DIR * dir)

功能:关闭dir所指的目录流
返回值:成功返回0;失败返回-1