一.文件操作
1.1 Linux文件系统结构
1.1.1 Linux常见系统目录
/bin : 存放普通系统可执行的命令(ls wc等)
/sbin : 存放系统管理程序(fsck等)
/boot : 存放内核和系统启动时所需的文件
/dev : 设备文件(磁盘、光驱)
/proc : proc虚拟文件系统,可以查看和配置系统运行状况(/poc/meminfo /proc/cpuinfo)
/usr : 存放系统应用程序及相关文件(帮助文档、说明文件)
/root : 超级用户root主目录
/home: 每个普通用户在其下有对应用户名的主目录
/etc : 存放系统配置文件(/etc/passwd、/etc/shadow)
/var : 存放文件系统中经常变化的文件(日志文件、用户文件)
/tmp : 存放临时文件的目录
/lib : 存放库文件
1.1.2 Linux的文件系统模型
Linux文件系统模型结构图:
1.对物理磁盘的访问必须通过设备驱动程序进行.
2.存在两种访问设备驱动的方式:
a.通过设备驱动程序提供的接口----设备API
b.通过虚拟文件系统(VFS)提供给上层应用程序的接口----文件API
3.虚拟文件系统(VFS)整合不同的文件系统(EXT2,EXT3,vfat..),为上层应用程序提供统一的访问接口
4.扇区是对物理磁盘访问的最小单位(盘面、磁道、扇区),文件系统由块组成,块大小对应扇区大小,取决于文件系统类型
1.1.3 Linux文件类型
Linux下有7种文件类型:
1.普通文件(-):包含某种形式的数据,是文本还是二进制由应用决定
2. 目录文件(d):
3. 字符特殊文件(c):系统中字符类型的设备(鼠标、键盘等)
4. 块特殊文件(b):系统中块类型的设备(磁盘、光驱等)
5. FIFO:命名管道,用于进程间通信
6. socket:套接字,用于网络通信
7. 符号链接(symbolic link):另一文件的引用
1.1.4 文件访问权限控制
mode_t: 32位位码 0-7:设置权限位 8-15:所有者权限 16-23:组权限 24-31:其他用户权限
r-4 w-2 x-1
chmod系统调用(改变文件权限):
#include
#include
int chmod(const char* path,mode_t mode);
int fchmod(int filedes,mode_t mode)
mode是以下权限位的组合: S_IRUSR S_IWUSR S_IXUSR ... S_IRGRP.... S_IROTH...S_ISUID S_ISGID S_ISVTX
1.2 文件的输入输出
1.2.1 文件的创建、打开与关闭
1.2.1.1 创建open
#include
#include
#include
int open(const char* pathname,int flag,mode_t mode);
int open(const char* pathname,int flag);
flag 指定文件打开方式(O_RDONLY O_WRONLY O_RDWR)
O_CREAT:若文件不存在则创建文件
O_EXCL: 若指定了O_CREAT,则声明该打开方式会对文件存在进行检查,若不存在创建,若存在报错返回
O_TRUNC:若文件存在则清空文件内容(以可写方式打开)
O_SYNC: 以同步方式打开文件,任何对文件的修改都会阻塞直到物理磁盘上的数据同步以后打开
O_NDELAY或O_NONBLOCK:非阻塞操作打开文件 对于open以及后续对该文件的操作都会立即返回
O_DIRECTORY:打开目录
O_NOFOLLOW:如果pathname是一个链接 打开出错
O_APPEND:写入的数据会以追加的方式加入到文件后面
新创建的文件的存取权限是 mode&~umask
1.2.1.2 创建(creat)
int creat(const char* pathname,mode_t mode);
若文件存在则会被覆盖
相当于 open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
1.2.1.3 关闭
#include
int close(int fd);
1.2.2 文件读写
#include
ssize_t read(int fd,void* buf,size_t count);
/*返回0,表示到文件末尾;-1,读取出错;返回读到的字节数;将读到的字节数与count比较*/
ssize_t write(int fd,const void* buf,size_t count);
1.2.3 文件读写指针的移动
#include
#include
off_t lseek(int fd,off_t offset,int whence);
/*出错返回-1;否则返回当前相对于文件开头的文件读写指针偏移量*/
SEEK_END:偏移相对于文件末尾 此时offset为正 则将文件读写指针移至文件末尾后
SEEK_SET:设置相对于文件开头的偏移量
SEEK_CUR:设置相对于当前文件读写指针的偏移量
lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_CUR);
lseek(fd,0,SEEK_SET);
1.2.4 dup,dup2,fcntl,iocel系统调用
1.2.4.1 dup和dup2(复制文件描述符)
#include
int dup(int oldfd);
int dup2(int oldfd,int newfd);
/*成功:返回最小的未被使用的文件描述符(dup) 或者返回newfd*/
/*效果:新复制的文件描述符与原文件描述符指向同一个文件,共享所有的锁定、
文件读写指针、各项权限、标志位*/
1.2.4.2 fcntl函数(进行各种控制操作以获取或者设置已打开文件的属性)
#include
#include
#include
int fcntl(int fd,int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock* lock);
/*根据cmd,进行控制操作*/
cmd:
F_DUPFD(dup功能)
F_GETFD(获取fd对应的文件的close-on-exec标识)
如果返回值的最后一位为1,则close-on-exec为1,执行exec将关闭该文件
F_SETFD(将fd对应文件的close-on-exec标识设置为arg最后一位)
F_GETFL(获取fd对应的文件的文件打开方式,与open的flag标识相同)
[accmode&O_ACCMODE(3)获得读取打开方式,accmode&O_APPEND获取O_APPEND标识]
F_SETFL(设置已打开文件的打开方式,只能设置O_ASYNC O_APPEND O_NONBLOCK标识)
/*文件记录锁*/
F_SETLK(对文件特定区域加锁,加锁方式由lock指定)
F_SETLKW(对文件特定区域加锁,加锁方式由lock指定,等待)
F_GETLK(测试能否以lock指定方式对文件加锁,若可,不执行加锁动作,将lock->l_type置为F_UNLCK,返回;
否则返回一个不能加锁的加锁方式至lock所指结构)
struct flock
{
short l_type; /*锁类型 F_RDLCK F_WRLCK*/
short l_whence; /* SEEK_SET SEEK_END SEEK_CUR*/
off_t l_start; /*锁起始位置*/
off_t l_len; /*被锁记录字节数*/
pid_t pid; /*锁的属主进程*/
};
若l_len为0,表示锁的区域从其起始区域直至最大可能位置为止.
锁整个文件 l_whence SEEK_SET;l_start 0;l_len 0
Linux系统的文件记录锁是建议性锁 非强制性锁.
F_GETOWN:返回当前接收SIGIO或者SIGURG的进程ID或者进程组ID(负数返回)
F_SETOWN:设置当前接收SIGIO或者SIGURG的进程ID或者进程组ID(负数设置)
F_SETSIG:设置输入输出时发出的信号
F_GETSIG:返回输入输出时收到的信号
1.2.4.3 ioctl函数
#include
int ioctl(int fd,int request,...);
/*获取或者设置设备文件的属性,第三个参数一般是char* argp,根据request不同来决定是get还是set*/
从socket总获取网卡的硬件地址
1.3 文件属性操作
ls -l 文件输出结果解析:
1.3.1 获取文件属性
#include
#include
#include
int stat(const char* file_name,struct stat* buf);
int fstat(int fd,struct stat* buf);
int lstat(const char* file_name,struct stat* buf);
/*将file_name或者fd对应文件的文件属性填充入buf所指结构*/
struct stat
{
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
blksize_t st_blksize;
blkcnt_t st_blocks;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
文件类型测试宏,用于测试st_mode包含的文件信息:
S_ISLINK(st_mode):判断是否为符号链接
S_ISREG:是否为普通文件
S_ISDIR S_ISCHR S_ISBLK S_ISFIFO S_ISSOCK
1.3.2 设置文件属性
1.3.2.1 改变文件访问权限
1.3.2.2 修改文件的用户id和群组id(chown fchown lchown)
#include
#include
int chown(const char* path,uid_t owner,gid_t group);
int fchown(int fd,uid_t owner,gid_t group);
int lchown(const char* path,uid_t owner,gid_t group);
/*若owne或者group之一为-1,那么文件的用户id和群组id不会改变*/
/*只有超级用户才能改变文件所有者,文件所有者只能将文件群组id改为其所属用户组中之一*/
/* chown 会清楚文件的set-uid和set-gid位*/
1.3.2.3 truncate/funcate改变文件的大小
#include
#include
int truncate(const char* path,off_t length);
int ftruncate(int fd,off_t length);
/*截短或者'\0'填充*/
1.3.2.4 utime更新文件的st_mtime和st_atime
#include
#include
int utime(const char* filename,struct utimbuf* buf);
struct utime
{
time_t actime; /*access time*/
time_t modtime; /*modification time*/
};
#include
int utimes(char* filename,struct timeval* tvp);
/*如果buf或者tvp为NULL,则将st_atime和st_mtime更新为当前时间*/
1.3.2.5 umask设置文件创建屏蔽字
#include
#include
mode_t umask(mode_t mask);
/*返回旧的文件创建屏蔽字 与进程相关 mode&~mask*/
1.4 文件的移动和删除
1.4.1 文件的移动
rename系统调用修改文件名或者文件的位置
#include
int rename(const char* oldpath,const char* newpath);
/*若newpath存在 则会被删除*/
1.4.2 文件的删除
unlink删除文件 remove则既可删除文件、亦可删除空目录(unlink实际上是减少对文件的一个链接数)
#include
int unlink(const char* pathname);
int remove(const char* pathname);
/*对文件的链接数为0并且没有进程打开该文件 才能删除文件并释放其磁盘空间*/
1.5 目录操作
1.5.1 创建、删除目录
#include
#include
#include
int mkdir(const char* pathname,mode_t mode);
int rmdir(const char* pathname); /*只能删除由pathname指定的空目录*/
1.5.2 获取当前目录
#include
char* getcwd(char* buf,size_t size);
char* get_current_working_directory(void);
char* getwd(char* buf);
1.5.3 设置工作目录
int chdir(const char* path);
int fchdir(int fd); /*将进程当前工作目录改为由fd指定的目录*/
1.5.4 获取目录信息
/*打开目录,获取DIR* 目录流*/
#include
#include
DIR* opendir(const char* name); /*错误返回NULL,设置errno*/
/*读取目录*/
struct dirent* readdir(DIR* dir);
/*从dir所指向的目录中读取出目录项信息,返回一个struct dirent结构的指针*/
struct dirent
{
ino_t d_no; /* inode number*/
off_t d_off; /*offset to this dirent*/
unsigned short d_reclen; /*length of this d_name*/
char d_name[NAME_MAX+1]'; /*file-name(null-terminated)*/
};
d_off目录文件开头至此文件进入点的位移
/*关闭目录*/
int closedir(DIR* dir);