Linux文件操作(二)
- 导语
- 文件和目录维护
- chmod
- chown
- link及其变体
- dir及其变体
- chdir和getcwd
- 扫描目录
- opendir
- readdir
- telldir
- seekdir
- closedir
- 示例程序
- 错误处理
- strerror
- perror
- /proc
- fcntl
- mmap相关
- mmap
- msync
- munmap
- 总结
- 参考文献
导语
文件操作的第二部分,介绍文件和目录相关操作,主要是目录,还有一些错误的处理方式
文件和目录维护
chmod
chmod是常用的修改文件的命令(这里是C语言的),用来修改文件和目录的权限,一般用户都可以调用,但是不一定都能成功操作,例如普通用户尝试操作系统文件,可能就会返回-1,函数原型如下
int chmod(const char *path, mode_t mode);
path为路径,mode为参数,它使用的参数和open一样
chown
chown供超级用户(管理员)使用,可以改变一个文件的属主
int chown(const char *path, uid_t owner, gid_t group);
给的参数分别是路径,用户id,组id,后两者是需要修改的目标
link及其变体
unlink调用时会删除文件的目录项并减少连接数,成功返回0,否则返回-1,但它操作的是目录项(即操作的其实是内存的目录项而不是外存的文件本身),如果想删除文件,需要当前用户拥有被操作文件的写和执行权限,实际上,当文件的链接数为0且无进程打开文件时,该文件会被自动删除
link调用会创建指向已有文件的新链接,它创建的是一个硬链接,可以认为给源文件加上一个引用
symlink是符号链接,是软链接,可以认为是快捷方式
具体的函数原型如下
int unlink(const char *path);
int link(const char *path1, const char *path2);
int symlink(const char *path1, const char *path2);
dir及其变体
mkdir用于创建一个新目录,函数原型如下
int mkdir(const char *path, mode_t mode);
path是新目录的名字,mode和open的参数一样,并且新目录服从umask的设置
rmdir用于删除目录,函数原型如下
int rmdir(const char *path);
参数就是待删除的目录,但前提是该目录为空,如果需要删除非空目录可以用命令rm -r,它会递归删除指定目录和其下的所有内容,但是这个操作基本不可逆转,如果在主目录里用会是毁灭性的
chdir和getcwd
chdir和shell中的cd很像,用来改变当前的工作目录,当然shell中也有一模一样的命令
getcwd是获取当前的工作目录,它会把当前目录名字写到缓冲区中,如果长度过长则会返回null,成功则返回缓冲区的首地址
两者的函数原型如下
int chdir(const char *path);
char *getcwd(char *buf, size_t size);//size是缓冲区大小
扫描目录
opendir
opendir是打开一个目录并建立一个目录流,成功则返回目录指针否则返回空,目录流通过一个底层文件描述符访问目录本身,文件过多可能会执行失败,即文件描述符耗尽,函数原型如下
DIR *opendir(const char *name);
readdir
readdir返回一个指针,该指针保留目录流中下一个目录项的有关资料,相当于遍历一个存目录项的数组,如果发生错误或者到目录尾,返回空,函数原型如下
struct dirent *readdir(DIR *dirp);
telldir
telldir记录一个目录流的当前位置,表示当前已经读取的目录项索引,可以认为是获得数组下标,原型如下
long int telldir(DIR *dirp);
seekdir
seekdir用来设置目录流的目录项指针,可以认为是数组中修改当前操作变量,原型如下
void seekdir(DIR *dirp, long int loc);
closedir
closedir用于关闭目录流,和opendir是逆操作
int closedir(DIR *dirp);
示例程序
错误处理
获取错误通常是通过errno变量来得到的,书上errno变量的取值部分如下,一般可以通过两个函数来报告出现的错误
strerror
strerror把错误映射成一个字符串,该字符串负责对发生的 错误类型进行说明,原型如下
char *strerror(int errnum);
perror
perror也是把报告的错误映射成一个字符串,但它的输出对象是stderr,并且它会在输出前先加上检测的对象冒号和空格,原型如下
void perror(const char *s);
/proc
Linux将任何事物都看成文件,即使是硬件设备,它提供了一个文件系统procfs,以proc目录展现,该目录下有许多用于操作驱动和内核的特殊文件,只要有对应的权限,就可以读写这些文件,以下是一个proc目录的例子
通常情况下,直接读取这些文件就可以获得设备或其他的状态信息,例如读取cpu的信息如下,每次读取这些文件的内容时,它们会及时更新,
/proc目录中的文件是可修改的,但是只有root权限才能修改,除此之外,还可以通过查看proc目录查看当前运行进程的细节,下面是一个查看bash的例子
fcntl
fcntl用于对打开的文件描述符执行操作,以下是书上给出的参数介绍
fcntl函数原型如下
in fcntl(int fildes, int cmd);
int fcntl(int fildes, int cmd ,long arg);
mmap相关
mmap
mmap用来实现一块可以被共用的内存,该部分内存可以被多个程序读写,mmap创建指向内存区域的指针,该区域可以与一个打开的文件描述符的内容相关联,函数原型如下
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
参数的意思分别是,申请的内存首地址,申请长度,访问权限,程序对内存段改变的影响,文件描述符,起始偏移值
参数的取值范围如下
flag:
msync
与mmap相关联的还有msync函数,它将内存段中的修改写回被映射的文件中,函数原型和flag的参数如下
int maync(void *addr, size_t len, int flags);
munmap
munmap是释放内存段,函数原型如下
int mumap(void *addr, size_t len);
总结
Linux对于文件和目录的操作非常多样化,并且大多是借助shell和C语言来实现的,相较于windows更简单一些
参考文献
- 《Linux程序设计(第4版)》