apue学习笔记(第四章 文件和目录)
本章将描述文件系统的其他特性和文件的性质。
函数stat、fstat、fstatat和lstat
#include <sys/stat.h>
int stat(const char *restrict pathname,struct stat *restrict buf);
int fstat(int fd,struct stat *buf);
int lstat(const char *restrict pathname,struct stat *restrict buf);
int fstatat(int fd,char *restrict pathname,struct stat *restrict buf,int flag);
一旦给出pathname,stat函数将返回与此命名文件相关的信息结构(存储在struct stat)
fstat函数获得已在描述符fd上打开文件的有关信息
lstat函数类似于stat,但是当命名文件时一个符号链接时,lstat返回该符号链接的有关信息,而不是该符号链接引用的文件的信息(符号链接有点像windows上的快捷方式)
stat结构基本形式如下:
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 */
};
文件类型
1 普通文件 包含某种形式的数据(文本或者二进制数据)
2 目录文件 包含了其他文件的名字以及指向这些文件有关信息的指针
3 块特殊文件 这种类型的文件提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度为单位进行
4 字符特殊文件 这种类型的文件提供对设备不带缓冲的访问,每次访问长度可变,系统中的所有设备要么是字符特殊文件,要么是块特殊文件
5 FIFO 这种类型的文件用于进程间通信,有时也称为命名管道
6 套接字 这种类型的文件用于进程间的网络通信
7 符号链接 这种类型的文件指向另一个文件
文件类型信息包含在stat结构的st_mode成员中,可以用宏确定文件类型,下面程序将打印出文件信息
#include "apue.h" int
main(int argc, char *argv[])
{
int i;
struct stat buf;
char *ptr; for (i = ; i < argc; i++) {
printf("%s: ", argv[i]);
if (lstat(argv[i], &buf) < ) {
err_ret("lstat error");
continue;
}
if (S_ISREG(buf.st_mode))
ptr = "regular";
else if (S_ISDIR(buf.st_mode))
ptr = "directory";
else if (S_ISCHR(buf.st_mode))
ptr = "character special";
else if (S_ISBLK(buf.st_mode))
ptr = "block special";
else if (S_ISFIFO(buf.st_mode))
ptr = "fifo";
else if (S_ISLNK(buf.st_mode))
ptr = "symbolic link";
else if (S_ISSOCK(buf.st_mode))
ptr = "socket";
else
ptr = "** unknown mode **";
printf("%s\n", ptr);
}
exit();
}
设置用户ID和设置组ID
与一个进程相关联的ID有6个或更多,如下图所示
1 实际用户ID和实际组ID标识我们究竟是谁。这两个字段在登录时取自口令文件中的登录项。
2 有效用户ID、有效组ID以及附属组ID决定了我们的访问权限,下一节将对此进行说明
3 保存的设置用户ID和保存的设置组ID在执行一个程序时包含了有效用户ID和有效组ID的副本
文件访问权限
每个文件有下面的9个访问权限位,st_mode值也包含了对文件的访问权限位
umask函数
umask函数为进程设置文件模式创建屏蔽字,并返回之前的值
#include <sys/stat.h>
mode_t umask(mode_t cmast);
参数cmask是上节列出的9个常量中的按若干个按位“或”组成的
下面程序创建两个程序,演示了umask函数的作用
#include "apue.h"
#include <fcntl.h> #define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) int
main(void)
{
umask();
if (creat("foo", RWRWRW) < )
err_sys("creat error for foo");
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (creat("bar", RWRWRW) < )
err_sys("creat error for bar");
exit();
}
下面是程序运行情况
我们用shell的umask命令在运行程序前后打印文件模式创建屏蔽字,可见更改进程的文件模式创建屏蔽字并不影响父进程(常常是shell)的屏蔽字
用户可以设置umask值以控制他们所创建文件的默认权限。该值表示成八进制数,一位代表一种屏蔽的权限,如下图所示
函数chmod、fchmod和fchmodat
#include <sys/stat.h>
int chmod(const char *pathname,mode_t mode);
int fchmod(int fd,mode_t mode);
int fchmodat(int fd,const char *pathname,mode_t mode,int flag);
chmod函数在指定的文件上进行操作,而fchmod函数则对已打开的文件进行操作。
参数mode是下图所示常量的按位或
下面程序修改了上节两个文件的模式
#include "apue.h" int
main(void)
{
struct stat statbuf; /* turn on set-group-ID and turn off group-execute */ if (stat("foo", &statbuf) < )
err_sys("stat error for foo");
if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < )
err_sys("chmod error for foo"); /* set absolute mode to "rw-r--r--" */ if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < )
err_sys("chmod error for bar"); exit();
}
下面是程序的运行情况
函数chown、fchown、fchownat和lchown
下面几个函数可用户更改文件的用户ID和组ID
#include <unistd.h>
int chown(const char *pathname,uid_t owner,gid_t group);
int fchown(int fd,uid_t owner,gid_t group);
int fchownat(int fd,const char *pathname,uid_t owner,gid_t group,int flag);
int lchown(const char *pathname,uid_t owner,gid_t gruop);
文件系统
我们可以把一个磁盘分成一个或多个分区,每个分区可以包含一个文件系统,如下图所示。i节点是固定长度的记录项,它包含有关文件的大部分信息。
把i结点跟数据块分离出来,则可以看到下图所示的情况
图中两个目录项指向同一个i节点。每个i节点都有一个链接计数,其值是指向该i节点的目录项数。只有当链接计数减少至0时,才可删除文件。
i节点包含了文件有关的所有信息:文件类型、文件的访问权限、文件长度和指向文件数据块的指针等。stat结构中大所属信息取自i节点。
函数link、linkat、unlink、unlinkat和remove
创建一个指向现有文件的链接的方法是使用link函数或linkat函数
#include <unistd.h>
int link(const char *existringpath,const char *newpath);
int linkat(int efd,const char *existingpath,int nfd,const char *newpath,int flag);
这两个函数创建一个新目录项newpath,它引用现有文件existringpath。只创建newpath最后一个分量,路径中的其他部分应当已经存在。
为了删除一个现有的目录项,可以调用unlink函数
#include <unistd.h>
int unlink(const char *pathname);
int unlink(int fd,const char *pathname,int flag);
这两个函数删除目录项,并将由pathname所引用文件的链接计数减1,只有当链接计数达到0时,该文件的内容才可被删除。
我们也可以用remove函数解除对一个文件或目录的链接。
#include <stdio.h>
int remove(const char *pathname);
函数rename和renameat
文件或目录可以用rename函数或者renameat函数进行重命名
#include <stdio.h>
int rename(const char *oldname,const char *newname);
int renameat(int oldfd,const char *oldname,int newfd,const char *newname);
符号链接
符号链接是对一个文件的间接指针,下图列出各个函数对符号链接的处理
创建和读取符号链接
下面函数创建一个指向actualpath的新目录项sympath。
#include <unistd.h>
int symlink(const char *actualpath,const char *sympath);
int symlinkat(const char *actualpath,int fd,const char *sympath);
因为open函数跟随符号链接,所以需要有一种方法打开该符号链接,并读取链接中的名字。下面函数提供了这种功能
#include <unistd.h>
ssize_t readlink(const char *restrict pathname,char *restrict buf,size_t bufsize);
ssize_t readkinkat(int fd,const char *restrict pathname,char *restrict buf,size_t bufsize);
两个函数组合了open、read和close的所有操作
文件的时间
对每个文件维护3个时间字段,它们的意义如下
下图列出我们已说明的各种函数对这3个时间的作用。
函数futimens、utimensat和utimes
一个文件的访问和修改时间可以用以下几个函数更改
#include <sys/stat.h>
int futimens(int fd,const struct timespec time[]);
int utimensat(int fd,const char *path,const struct timespec times[],int flag);
这两个函数的times数组的第一个元素包含访问时间、第二个元素包含修改时间。
timespec结构如下
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
如果times参数是一个空指针,则访问时间和修改时间两者都设置为当前时间。
utimes函数对路径名进行操作
#include <sys/time.h>
int utimes(const char *pathname,const struct timeval times[]);
timeval结构如下
struct timeval {
time_t tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
函数mkdir、mkdirat和rmdir
用mkdir和mkdirat函数创建目录,用rmdir函数删除目录
#include <sys/stat.h>
int mkdir(const char *pathname,mode_t mode);
int mkdirat(int fd,const char *pathname,mode_t mode);
用rmdir函数删除一个空目录。空目录是只包含.和..这两项的目录
#include <unistd.h>
int rmdir(const char *pathname);
读目录
对某个目录具有访问权限的任一用户都可以读该目录,一个目录的写权限位和执行权限位决定了在该目录中能否创建文件以及删除文件。
下面所示的是对读目录的一些函数
#include <dirent.h>
DIR *opendir(const char *pathname);
DIR *fdopendir(int fd); struct dirent *readdir(DIR *dp); void rewinddir(DIR *dp);
int closedir(DIR *dp); long telldir(DIR *dp); void seekdir(DIR *dp,long loc);
dirent结构与实现有关,实现对此结构所做的定义至少包含下列两个成员:
ino_t d_ino; /* i-node number */
char d_name[] /* null-terminated filename */
函数chdir、fchdir和getcwd
进程可以调用chdir或fchidr函数更改当前工作目录
#include <unistd.h>
int chdir(const char *pathname);
int fchdir(int fd);
跟umask函数一样,执行程序前后shell的当前工作目录并没有改变。
下面函数可以得到当前目录完整的绝对路径名
#include <unistd.h>
char *getcwd(char *buf,size_t size);
apue学习笔记(第四章 文件和目录)的更多相关文章
- 《UNIX环境高级编程》(APUE) 笔记第四章 - 文件和目录
4 - 文件和目录 1. 函数 stat.fstat.fstatat 和 lstat #inlcude <sys/stat.h> int stat(const char *restrict ...
- Java NIO 学习笔记(四)----文件通道和网络通道
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- [Python学习笔记][第四章Python字符串]
2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...
- apue学习笔记(第一章UNIX基础知识)
总所周知,UNIX环境高级编程是一本很经典的书,之前我粗略的看了一遍,感觉理解得不够深入. 听说写博客可以提高自己的水平,因此趁着这个机会我想把它重新看一遍,并把每一章的笔记写在博客里面. 我学习的时 ...
- o'Reill的SVG精髓(第二版)学习笔记——第四章
第四章:基本形状 4.1线段 SVG可以使用<line>元素画出一条直线段.使用时只需要指定线段起止点的x和y坐标即可.指定坐标时可以不带单位,此时会使用用户坐标,也可以带上单位,如em. ...
- [Linux] Linux学习笔记(5)-文件与目录管理
1.Linux目录结构为树状结构,最顶层的目录为跟目录"/",其它目录通过挂载可以将它添加到目录树中,通过解除挂载移除它们. 2.绝对路径与相对路径 绝对路径写法:由根目录&quo ...
- Linux学习之十四-Linux文件和目录权限
Linux文件和目录权限 在Linux中的每一个文件或目录都包含有访问权限,这些访问权限决定了谁能访问和如何访问这些文件和目录. 通过设定权限可以从以下三种访问方式限制访问权限:只允许用户自己访问:允 ...
- 《鸟哥的Linux私房菜》学习笔记(1)——文件与目录
在Linux中,任何设备都是文件,不仅如此,连数据通信的接口也有专门的文件负责.可以说,一切皆文件,目录也是一种文件,是路径映射.因此,文件系统是Linux的基础. 一.文件与目录管理命令 1.ls( ...
- UNIX系统高级编程——第四章-文件和目录-总结
文件系统: 以UNIX系统V文件系统为例: 磁盘分为区,每个分区都有自己的文件系统: i节点是固定长度的记录项,包含了文件的相关信息.目录项包含文件名和i节点号.stat结构中除文件名和i节点编号 ...
随机推荐
- LVS Mode&Method
LVS NAT 模式: Summary: 普通的NAT模式为DNAT,即只更改目的地址,不改源端口. LVS在转发报文时,将Client的源IP透传给Server,类似于透明传输. 优点: 1. 可提 ...
- 【08】node 之 fs文件
var fs = require("fs");//fs 系统文件模块,对文件进行操作.Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有 ...
- TJOI2015题解
(转载前请标明出处,谢谢) 打算来做一波TJOI2015,来写题解啦! Day1: T1:[bzoj3996] 题目链接:http://www.lydsy.com/JudgeOnline/proble ...
- WP7资源
原文发布时间为:2012-07-31 -- 来源于本人的百度文章 [由搬家工具导入] Code libraries and toolkits Enterprise Library 5.0provide ...
- 前端知识点总结——CSS
1.CSS的概述 1.什么是CSS? CSS:Cascading Style Sheets层叠样式表,级联样式表(简称:样式表) 2.作用 设置HTML网页元素的样式 3.HTML与CSS的关系 HT ...
- Android Bluetooth抓包
1. 前提 这里介绍一种在Android上捕获蓝牙数据包的方法 首先你要有一部Android手机:然后你的Android系统版本要在4.4及以上 我没有做过Android开发,不清楚开发者们是如何抓蓝 ...
- nginx报404的可能错误
1.转移地址写错,如root E:software_setup\ftpfile,而你实际的目录地址(比如test.jpg)在ftpfile文件夹里面的img文件夹下,如果直接找ftpfile\test ...
- 有道词典中的OCR功能:第三方库的变化
之前有点好奇有道词典中的OCR功能,具体来说就是强力取词功能.我知道的最有名的OCR库是tesseract,这个库是惠普在早些年前开源的. 在用python做爬虫处理验证码的时候,就会用到这个库,对应 ...
- 【转载】SQL Server XML Path
FOR XML PATH 有的人可能知道有的人可能不知道,其实它就是将查询结果集以XML形式展现,有了它我们可以简化我们的查询语句实现一些以前可能需要借助函数活存储过程来完成的工作.那么以一个实例为主 ...
- Bootstrap多层模态框modal嵌套问题
一.问题 在项目里忽然新加了一个需求,在原本弹出的模态框里,点击模态框里面的按钮再弹出一个模态框,出来另个模态框来展示详细信息.此时就存在两个模态框在这个需求没加之前有一个弹出的模态框也是需要继续点击 ...