文件描述符:在Linux系统中,打开的文件会对应一个数字(非负整数),这个由系统分配的数字我们
称之为文件描述符(file descriptor),具体可以看下这里的:Linux中的文件描述符与打开文件之间的关系 。
学习目标:
一、学习函数1、学习系统调用的函数:open,close,read,write,creat,lseek,dup;
2、编程:复制文件的程序。
1、open:打开或者创建一个文件或设备(Open and possibly create a file or device)
1)函数原型
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
2)所属头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
3)返回值
成功: 返回新的文件描述符
失败: -1
4)参数说明
*pathname: 包含路径的文件名(可以是绝对路径也可以是相对路径)
*flags: 文件打开的标志
使用O_RDONLY(只读), O_WRONLY(只写) 或 O_RDWR(可读可写) 与 O_CREAT(创建新文件)
O_APPEND(追加, 读写指针置于文件末尾) 相或(-or).
*O_CREAT: 若文件不存在则新建一个文件
若使用了O_CREAT则需要指定mode(文件权限), 但是mode通常会被umask(掩码)修改, 所以
一般创建的文件权限为(mode & ~umask),
2、close: 关闭一个文件描述符
1)函数原型
int close(int fd);
2)所属头文件
#include <unistd.h>
3)返回值
成功: 0
失败: -1
4)参数说明
fd: 带关闭的文件描述符
3、read: 在文件描述符上执行读操作(Read from a file descriptor)
1)函数原型
ssize_t read(int fd, void *buf, size_t count);
2)所属头文件
#include <unistd.h>
3)返回值
成功: 返回成功读取的字节数
失败: -1
4)参数说明
fd: 待读取的文件描述符
buf: 读取信息的缓冲数组
count: 读取字节数
4、write: 在文件描述符上执行写操作(Write to a file descriptor)
1)函数原型ssize_t write(int fd, const void *buf, size_t count);2)所属头文件
#include <unistd.h>
3)返回值
成功: 返回成功写入的字节数
失败: -1
4)参数说明
fd: 待写入数据的文件描述符
buf: 待写入的数据缓冲数组
count: 待写入数据的字节数
5、creat: 创建一个文件, 并以只写的方式打开该文件
1)函数原型
int creat(const char *pathanme, mode_t mode);
2)所属头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
3)返回值
成功: 返回新建的文件描述符
失败: -1
4)参数说明
pathname: 创建的文件名(包含路径)
mode: 设置文件权限
6、lseek: 重新定义文件读写的偏移量
1)函数原型
off_t lseek(int fd, off_t offset, int whence);\
2)所属头文件
#include <sys/types.h>
#include <unistd.h>
3)返回值
成功: 返回产生的偏移量(距离文件头的位置)
失败: -1
4)参数说明
fd: 要重置的文件描述符
offset: 要便宜的量
whence: 偏移开始的位置
* SEEK_SET: 从文件头
* SEEK_CUR: 从当前位置
* SEEK_END: 从文件尾
7、dup: 复制一个文件描述符(Duplicate a file descriptor)
1)函数原型int dup(int old fd);int dup(int old, int newfd);2)所属头文件
#include <unistd.h>
3)返回值
成功: 返回新的文件描述符
失败: -1
4)参数说明
oldfd: 源文件描述符
newfd: 目标文件描述符
二、最佳实践
* 编写copy程序:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BUF_SIZE 512
void main(int argc, char* argv[])
{
int fd_src = 0;
int fd_dest = 0;
int count = 0;
int buf[BUF_SIZE];
/* 1. 打开源文件 */
fd_src = open(argv[1], O_RDONLY);
/* 2. 打开目标文件 */
fd_dest = open(argv[2], O_WRONLY|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
/* 3. 读取源文件的数据, 写入到目标文件 */
while ( (count = read(fd_src, buf, BUF_SIZE)) > 0)
{
write(fd_dest, buf, count);
}
/* 4. 关闭目标文件 */
close(fd_dest);
/* 5. 关闭源文件 */
close(fd_src);
# 这里采用命令行参数
argc: 参数个数
argv[0]: 程序名
argv[1]: 第一个参数, 以此类推第二个第三个,,,,,
/* 2. 打开目标文件 */
fd_dest = open(argv[2], O_WRONLY|O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO);
这里可以看出, 我们给出的是所有用户可读可写可执行. 然而由于umask的影响结果却不如所愿
这里权限正好为(mode & ~umask).