linux 系统编程—文件/文件系统
优先使用库函数
摘自黑马程序员配套视频
命令
strace
查看程序使用的系统调用
文件操作
open
int open(char *pathname, int flags)
作用:
打开文件
参数:
pathname: 文件的路径
flags: 文件的打开的方式
返回值:
成功: 打开文件所得到对应的 文件描述符 (整数)
失败: -1, 设置errno
int open(char *pathname, int flags, mode_t mode)
作用:
打开文件
参数:
pathname: 欲打开文件路径名
flags: 文件的打开的方式
mode: 使用的前提为,参数flags指定了O_CREAT 8进制,用来描述文件的访问权限(rwx)
创建文件的最终的权限为 mode & ~umask
返回值:
成功: 打开文件所得到对应的 文件描述符 (整数)
失败: -1, 设置errno
close
int close(int fd)
作用:
关闭文件
read
ssize_t read(int fd, void *buff, size_t count)
参数:
fd: 文件描述符
buf: 存数据的缓冲区
count: 缓冲区的大小
返回值:
0: 读到了文件的末尾
成功: 读到的字节数
失败: -1, 设置errno
-1: , 并且errno = EAGAIN 或 EWOULDBLOCK, 说明不是read失败, 而是read在以非阻塞方式读一个设备文件(网络文件), 并且文件无数据
注:
无用户级缓冲
write
ssize_t write(int fd, const void *buff, size_t count)
参数:
fd: 文件描述符
buf: 待写出数据的缓冲区
count: 写出的内容的大小
返回值:
成功: 读到的字节数
失败: -1, 设置errno
注:
无用户级缓冲
文件描述符
0 - STDIN_FILENO 标准输入
1 - STDOUT_FILENO 标准输出
2 - STDERR_FILENO 标准错误
fcntl
int fcntl(int fd, int cmd, ... /* arg */ );
功能描述:根据文件描述词来操作文件的特性。
获取文件状态: F_GETFL
设置文件状态: F_SETFL
strerror
char *strerror(int errnum)
参数:
errnum: 错误号,通常是 errno
返回值:
一个指向错误字符串的指针,该错误字符串描述了错误 errnum
perror
void perror(const char *str)
参数:
str: 这是 C 字符串,包含了一个自定义消息,将显示在原本的错误消息之前。
lseek
off_t lseek(int fd, off_t offset, int whence);
参数:
fd: 文件描述符
offset: 文件偏移量
whence: 起始偏移位置 SEEK_SET / SEEK_CUR / SEEK_END
返回值:
成功: 较起始位置的偏移量
失败: -1, 设置errno
注: 文件的读和写使用的同一个偏移位置
拓展:
可以使用lseek来获取拓展文件的大小
stat
描述:
获取文件的属性
int stat(const char *path, struct stat *buf);
参数:
path: 文件路径
buf: 传出参数, 存放文件的属性
返回值:
0: 成功
-1: 失败, 设置errno
注:
有stat穿透现象,即不能查看符号连接类型, 若要查看符号链接类型, 则需要用lsate
stat 结构体的内容
包含在 sys/stat.h
的头文件中
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
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 file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
可以通过 st_mode
来调用宏函数来做更多的操作
S_ISREG(m) is it a regular file?
S_ISDIR(m) directory?
S_ISCHR(m) character device?
S_ISBLK(m) block device?
S_ISFIFO(m) FIFO (named pipe)?
S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)
S_ISSOCK(m) socket? (Not in POSIX.1-1996.)
lstat
int stat(const char *path, struct stat *buf);
与 state 用法完全一样
区别:
穿透符号链接: stat: 会, lstat: 不会
link
int link(const char *oldpath, const char *newpath);
参数:
oldpath: 旧文件的路径
newpath: 新的文件的路径
返回值:
0: 成功
-1: 失败
unlink
int unlink(const char *pathname);
参数: 被删除文件的路径
当被unlink以后,文件具备了被删除的条件, 当文件没有被其他的进程使用的时候, 系统会将其删除
readlink
读取符号链接文件本身的内容, 得到链接所指向的文件名
ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
参数:
pathname: 待读取的文件的路径
buf: 文件缓冲区
bufsiz: 读取的文件的大小
返回值:
成功: 读到的字节数
失败: -1, 设置 errno
rename
int rename(const char *oldpath, const char *newpath);
参数:
oldpath: 旧文件的路径
newpath: 新的文件的路径
目录操作
getcwd
char *getcwd(char *buf, size_t size);
参数:
buf: 读取出来的字符串的存放的位置
size: 缓冲区的大小
返回值:
当前目录所在的位置, 和 buf 的内容一致
chdir
int chdir(const char *path);
参数:
path: 前往的文件夹的路径
返回值:
成功: 0
失败: -1, 设置 errno
opendir
DIR *opendir(const char *name);
参数:
name: 文件夹的名字, 可以是相对路径, 也可以是绝对路径
返回值:
成功: 指向该目录结构体的指针
失败: NULL
closedir
int closedir(DIR *dirp);
参数:
dirp: 指向目标目录结构体的指针
返回值:
成功: 0
失败: -1, 设置errno
readdir
struct dirent *readdir(DIR *dirp);
参数:
dirp: 指向目标目录结构体的指针
返回值:
成功: 返回目录项
失败: NULL, 设置 errno
dirent结构体的内容
struct dirent {
ino_t d_ino; /* Inode number */
off_t d_off; /* Not an offset; see below */
unsigned short d_reclen; /* Length of this record */
unsigned char d_type; /* Type of file; not supported
by all filesystem types */
char d_name[256]; /* Null-terminated filename */
};
dup和dup2
int dup(int oldfd)
参数:
oldfd: 已有的文件的描述符
返回值:
成功: 新的文件描述符
失败: -1, 设置errno
作用:
添加一个文件描述符的拷贝, 两个文件操作符指向同一个文件
int dup2(int oldfd, int newfd);
参数:
oldfd: 已有的文件描述符
newfd: 新的文件描述符
返回值:
成功: 新的文件描述符
失败: -1, 设置errno
作用:
可以指定文件描述符的拷贝
应用
重定向文件输出, 可以讲输出到屏幕上的内容输出到文件中
将 1 修改
fcntl函数实现dup
int fcntl(int fd, int cmd, ...)
参数:
cmd: F_DUPFD
参3: 返回由 n 开始的第一个未被占用的最小的文件描述符