横沥做网站的电话,建网站盈利,国际新闻最新消息今天新闻,制作一个手机app需要多少钱1. VFS虚拟文件系统
Linux支持各种各样的文件系统格式#xff0c;如ext2、ext3、reiserfs、FAT、NTFS、iso9660 等等#xff0c;不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式#xff0c;然而这些文件系统 都可以mount到某个目录下#xff0c;使我们看到一个…1. VFS虚拟文件系统
Linux支持各种各样的文件系统格式如ext2、ext3、reiserfs、FAT、NTFS、iso9660 等等不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式然而这些文件系统 都可以mount到某个目录下使我们看到一个统一的目录树各种文件系统上的目录和文件 我们用ls命令看起来是一样的读写操作用起来也都是一样的这是怎么做到的呢?Linux 内核在各种不同的文件系统格式之上做了一个抽象层使得文件、目录、读写访问等概念成 为抽象层的概念因此各种文件系统看起来用起来都一样这个抽象层称为虚拟文件系统 (VFSVirtual Filesystem)。这一节我们介绍运行时文件系统在内核中的表示。 1.1 dup/dup2
#include unistd.h
int dup(int oldfd);
int dup2(int oldfd, int newfd);dup和dup2都可用来复制一个现存的文件描述符使两个文件描述符指向同一个file结 构体。如果两个文件描述符指向同一个file结构体File Status Flag和读写位置只保存一份在file结构体中并且file结构体的引用计数是2。如果两次open同一文件得到两个文件 描述符则每个描述符对应一个不同的file结构体可以有不同的File Status Flag和读写 位置。请注意区分这两种情况。
#include unistd.h
#include sys/stat.h
#include fcntl.h
#include stdio.h
#include stdlib.h
#include string.h
int main(void) {int fd, save_fd;char msg[] This is a test\n;fd open(somefile, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if(fd0) {perror(open);exit(1); }save_fd dup(STDOUT_FILENO);dup2(fd, STDOUT_FILENO);close(fd);write(STDOUT_FILENO, msg, strlen(msg)); dup2(save_fd, STDOUT_FILENO); write(STDOUT_FILENO, msg, strlen(msg)); close(save_fd);return 0;
}示例 2. 常用文件操作
2.1 stat
#include sys/types.h #include sys/stat.h #include unistd.h
int stat(const char *path, struct stat *buf); int fstat(int fd, struct stat *buf);
int lstat(const char *path, struct stat *buf);
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 */stat既有命令也有同名函数用来获取文件Inode里主要信息stat 跟踪符号链 接lstat不跟踪符号链接
stat里面时间辨析
atime(最近访问时间): mtime(最近更改时间):指最近修改文件内容的时间 ctime(最 近改动时间):指最近改动Inode的时间 ## access
#include unistd.h
int access(const char *pathname, int mode);按实际用户ID和实际组ID测试,跟踪符号链接 参数mode
R_OK 是否有读权限
W_OK 是否有写权限
X_OK 是否有执行权限
F_OK 测试一个文件是否存在实际用户ID: 有效用户ID:sudo执行时有效用户ID是root实际用户ID是xingwen- peng
2.1 chmod
#include sys/stat.h
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);2.2 chown
#include unistd.h
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);chown使用时必须拥有root权限。 2.3 utime
2.4 truncate
#include unistd.h #include sys/types.h
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);2.4 link
2.4.1 link
创建一个硬链接
当rm删除文件时只是删除了目录下的记录项和把inode硬链接计数减1当硬链接计数 减为0时才会真正的删除文件。
#include unistd.h
int link(const char *oldpath, const char *newpath);硬链接通常要求位于同一文件系统中,POSIX允许夸文件系统符号链接没有文件系统限制通常不允许创建目录的硬链接某些unix系统下超级用户可以创建目录的硬链创建目录项以及增加硬链接计数应当是一个原子操作
2.4.2 symlink int symlink(const char *oldpath, const char *newpath)2.4.3 readlink
读符号链接所指向的文件名字不读文件内容 ssize_t readlink(const char *path, char *buf, size_t bufsiz)2.4.4 unlink
int unlink(const char *pathname)如果是符号链接删除符号链接如果是硬链接硬链接数减1当减为0时释放数据块和inode如果文件硬链接数为0但有进程已打开该文件并持有文件描述符则等该进程关闭该文件时kernel才真正 去删除该文件利用该特性创建临时文件先open或creat创建一个文件马上unlink此文件
2.5 rename
文件重命名
#include stdio.h
int rename(const char *oldpath, const char *newpath);2.6 chdir
#include unistd.h
int chdir(const char *path);
int fchdir(int fd);改变当前进程的工作目录。
2.7 getcwd
获取当前进程的工作目录
#include unistd.h
char *getcwd(char *buf, size_t size);2.8 pathconf
#include unistd.h
long fpathconf(int fd, int name);
long pathconf(char *path, int name);3. 目录操作
3.1 mkdir
#include sys/stat.h
#include sys/types.h
int mkdir(const char *pathname, mode_t mode);3.2 rmdir
#include unistd.h
int rmdir(const char *pathname);3.3 opendir/fdopendir
#include sys/types.h
#include dirent.h
DIR *opendir(const char *name);
DIR *fdopendir(int fd);3.4 readdir
#include dirent.h
struct dirent *readdir(DIR *dirp);readdir每次返回一条记录项DIR*指针指向下一条记录项
3.5 rewinddir
#include sys/types.h
#include dirent.h
void rewinddir(DIR *dirp);把目录指针恢复到目录的起始位置。
3.6 telldir/seekdir
#include dirent.h
long telldir(DIR *dirp);#include dirent.h
void seekdir(DIR *dirp, long offset);3.7 closedir
#include sys/types.h
#include dirent.hint closedir(DIR *dirp);3.8 递归遍历目录
递归列出目录中的文件列表
#include sys/types.h
#include sys/stat.h
#include unistd.h
#include dirent.h
#include stdio.h
#include string.h
#define MAX_PATH 1024
/* dirwalk: apply fcn to all files in dir */
void dirwalk(char *dir, void (*fcn)(char *)) {char name[MAX_PATH]; struct dirent *dp; DIR *dfd;if ((dfd opendir(dir)) NULL) { fprintf(stderr, dirwalk: cant open %s\n,dir);return;}while ((dp readdir(dfd)) ! NULL){ if (strcmp(dp-d_name, .) 0|| strcmp(dp-d_name, ..) 0)continue; /* skip self and parent */if (strlen(dir)strlen(dp-d_name)2 sizeof(name))fprintf(stderr, dirwalk: name %s %s too long\n, dir, dp-d_name);else {sprintf(name, %s/%s, dir, dp-d_name); (*fcn)(name);} }closedir(dfd);
}
/* fsize: print the size and name of file name */
void fsize(char *name)
{
struct stat stbuf;
if (stat(name, stbuf) -1) {
fprintf(stderr, fsize: cant access %s\n, name); return;
}
if ((stbuf.st_mode S_IFMT) S_IFDIR)
dirwalk(name, fsize);
printf(%8ld %s\n, stbuf.st_size, name);
}
int main(int argc, char **argv) {if (argc 1) /* default: current directory */ fsize(.);elsewhile (--argc 0)fsize(*argv); return 0;
}然而这个程序还是不如ls -R健壮它有可能死循环思考一下什么情况会导致死循环。
4. 小结
本文介绍了Virtual FilesystemVFS虚拟文件系统及其原理以及stat、chmod、chown、utime等常用文件操作函数以及mkdir、rmdir、readdir等目录操作函数。