2021-10-02

本文详细探讨了文件系统的各种操作,包括不同BUFSIZE对mycp命令效率的影响,文件共享,原子操作,同步机制如sync、fsync、fdatasync,以及文件权限管理。还介绍了stat结构体用于获取文件属性,文件大小的获取,硬链接和符号链接的区别,以及文件权限的bitmap表示。同时,讨论了目录操作如mkdir、rmdir,以及如何删除文件的特定行。
摘要由CSDN通过智能技术生成

IO的效率问题

习题:
设置不同的BUFSIZE,查看mycp命令所耗的时间。BUFSIZE[128-16M],3-5GB大小的文件
出具表格,realtime,usertime,systime,循环次数,分析拐点,以及何时出错。

文件共享:多个任务共同操作一个文件或者协同完成任务。
面试题:写程序(使用系统IO)删除一个文件的第10行。
补充函数:truncate/ftruncate

方法一、
while(){
	lseek 11 
	read
	lseek 10
	write
}
====================================
方法二、对同一个文件打开两次
open  r	fd1 lseek 11
open  r+	fd2  lseek10
fd1 read
fd2 write
方法三、多进程或多线程
一个读、一个写

原子操作

不可分割的最小单位
原子操作:不可分割的操作。
原子操作的作用:解决竞争和冲突。
如tmpnam

dup、dup2

同步

sync:同步内核buffer cache至磁盘
fsync:
fdatasync:之刷新非元数据

fcntl函数

管家级函数

       #include <unistd.h>
       #include <fcntl.h>

       int fcntl(int fd, int cmd, ... /* arg */ );

ioctl函数

管理所有设备相关的内容

       #include <sys/ioctl.h>
       int ioctl(int fd, unsigned long request, ...);

/dev/fd/ 虚目录

当前进程的文件描述符信息,类似照镜子,谁看就是谁的。

文件系统

类似ls的实现,myls命令

command -短格式 --长格式 param1,param2 ...

一、目录(会用到递归)和文件

  1. 如何获取文件属性?
    stat,fstat,lstat
  2. 如何控制文件的访问权限
    mode_t,16位bitmap,表示文件类型,文件访问权限,以及特殊权限位
  3. umask
  4. 如何更改文件权限/管理?
  5. 什么是粘着位?
  6. 文件系统FAT ,UFS是什么东西?
  7. 什么是硬链接,符号链接?
  8. utime
  9. 目录的创建和销毁
    mkdir、rmdir
  10. 更改当前工作路径
    chdir、fchdir
  11. 分析目录/读取目录内容

二、系统数据文件和信息

三、当前的进程环境

stat

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

       int stat(const char *pathname, struct stat *statbuf); //获取文件属性信息,填到buf
       int fstat(int fd, struct stat *statbuf);
       int lstat(const char *pathname, struct stat *statbuf);

           struct stat {
               dev_t     st_dev;         /* ID of device containing file */ 包含当前文件的设备ID号
               ino_t     st_ino;         /* Inode number */ 
               mode_t    st_mode;        /* File type and mode */ 文件类型和权限
               nlink_t   st_nlink;       /* Number of hard links */ 硬链接数
               uid_t     st_uid;         /* User ID of owner */ UID
               gid_t     st_gid;         /* Group ID of owner */ GID
               dev_t     st_rdev;        /* Device ID (if special file) */
               off_t     st_size;        /* Total size, in bytes */ 总字节数
               blksize_t st_blksize;     /* Block size for filesystem I/O */ 块大小
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */ 多少个512块

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec
           #define st_ctime st_ctim.tv_sec
           };

stat函数使用

#include <stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static off_t flen(const char *fname){
    struct stat statres;
    if(stat(fname,&statres)<0){
        perror("stat error");
        exit(1);
    }
    return statres.st_size;
}
int main(int argc, char const *argv[])
{
    if (argc<2)
    {
        fprintf(stderr,"Usage....\n");
        exit(1);
    }
    printf("total size: %ld ",flen(argv[1]));
    exit(0);
}

写程序做一个大文件

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main(int argc, char const *argv[])
{
    int fd;
    if (argc<2)
    {
        fprintf(stderr,"Usages....");
        exit(1);
    }
    fd=open(argv[1],O_WRONLY|O_CREAT|O_TRUNC,0600);
    if (fd<0)
    {
            perror("open()");
            exit(1);
    }
    lseek(fd,5LL*1024LL*1024LL*1024LL-1LL,SEEK_SET); //int型会溢出
    write(fd,"",1);
    close(fd);
    exit(0);
}

Size:文件大小
Blocks:占用空间
在这里插入图片描述

mode_t

           struct stat {
               dev_t     st_dev;         /* ID of device containing file */ 包含当前文件的设备ID号
               ino_t     st_ino;         /* Inode number */ 
               mode_t    st_mode;        /* File type and mode */ 文件类型和权限
               ...
           }
           mode_t  以bitmap形式存储,16位
           文件类型7种,user,group,others,u+s,g+s,粘着位
           3位				 9位 			3位  		一共15位           
           所以需要一个16位的bitmap来存储

文件类型:dcb-lsp
d 目录
c 字符设备文件
b 块文件
- 普通文件
l 符号连接(硬链接)
s 网络套接字
p 管道文件(命名管道)

示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
static int ftype(const char *fname){
    struct stat statres;
    if(stat(fname,&statres)<0){
        perror("stat()");
        exit(1);
    };
    if(S_ISREG(statres.st_mode)) return '-';
    if(S_ISDIR(statres.st_mode)) return 'd';
    if(S_ISCHR(statres.st_mode)) return 'c';
    if(S_ISBLK(statres.st_mode)) return 'b';
    if(S_ISFIFO(statres.st_mode)) return 'p';
    if(S_ISLNK(statres.st_mode)) return 'l';
    if(S_ISSOCK(statres.st_mode)) return 's';
    return '?';
}
int main(int argc, char const *argv[])
{
    if(argc<2 ){
        fprintf(stderr,"Usage......\n");
        exit(1);
    }
    printf("the type of %s is %c\n",argv[1],ftype(argv[1]));
    exit(0);
}

在这里插入图片描述

权限bitmap,上图为八进制数

16位整型数
1111 000 000 000 000	S_IFMT
1100 000 000 000 000	S_IFSOCK
1010 000 000 000 000	S_IFLINK
1000 000 000 000 000	S_IFREG
0110 000 000 000 000	S_IFBLK
0100 000 000 000 000	S_IFDIR
0010 000 000 000 000	S_IFCHR
0001 000 000 000 000	S_IFIFO

0000 100 000 000 000	S_ISUID	设置UID
0000 010 000 000 000	S_ISGID	设置GID
0000 001 000 000 000	S_ISVTX	粘着位

0000 000 111 000 000	S_IRWXU
0000 000 100 000 000	S_IRUSR
0000 000 010 000 000	S_IWUSR
0000 000 001 000 000	S_IXUSR

0000 000 000 111 000	S_IRWXG
0000 000 000 100 000	S_IRGRP
0000 000 000 010 000	S_IWGRP
0000 000 000 001 000	S_IXGRP

0000 0000 00 000 111	S_IRWXO
0000 000 000 000 100	S_IROTH
0000 000 000 000 010	S_IWOTH
0000 000 000 000 001	S_IXOTH

umask函数

防止产生权限过松的文件

       umask - set file mode creation mask
       #include <sys/types.h>
       #include <sys/stat.h>
       mode_t umask(mode_t mask);

文件权限更改
chmod、fchmod

NAME
       chmod, fchmod, fchmodat - change permissions of a file

SYNOPSIS
       #include <sys/stat.h>

       int chmod(const char *pathname, mode_t mode);
       int fchmod(int fd, mode_t mode);

粘着位

又称t位,
原本的作用:给某一个可执行的二进制命令设置t位,作用是保留命令的使用痕迹,下次装载模块是会比较快。
现在的作用:各个用户对目录的操作特殊化

文件系统FAT

文件系统:文件或数据的存储和管理。
FAT不开源,UFS开源
FAT文件系统核心:
FAT16/32:静态存储的单链表(array),单链表单向的,一式两份,出现差错无法定位哪个哪一份错误
在这里插入图片描述

文件系统UFS

在这里插入图片描述
在这里插入图片描述
文件名在目录文件中
在这里插入图片描述

面试题:要求使用bitmap。
①封装一个函数,比较两个32位无符号整数的大小,返回较大的那个数,要求不能使用比较和判断。
②一个无符号32位整数,例如93,它的二进制形式里有多少个0?多少个1?
使用移位判断,或者使用bitmap

硬链接

硬链接是目录项的同义词。
ln给文件做硬链接,其实就是在目录文件中写入一个目录项,这个目录项的inode与源文件的inode值一样

  1. 硬链接与目录项是同义词
  2. 不能给分区、目录建立硬链接
  3. 符号链接可以跨分区,可以给目录建立
lry@ubuntu:~/codes/fs$ stat cool
  File: cool
  Size: 5368709120      Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 2883778     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     lry)   Gid: ( 1000/     lry)
Access: 2021-10-02 11:00:22.490656951 +0800
Modify: 2021-10-02 10:59:00.306109455 +0800
Change: 2021-10-02 10:59:00.306109455 +0800
 Birth: -
lry@ubuntu:~/codes/fs$ ln cool cool_link
lry@ubuntu:~/codes/fs$ stat cool
  File: cool
  Size: 5368709120      Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 2883778     Links: 2
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     lry)   Gid: ( 1000/     lry)
Access: 2021-10-02 11:00:22.490656951 +0800
Modify: 2021-10-02 10:59:00.306109455 +0800
Change: 2021-10-02 15:09:01.247004439 +0800
 Birth: -
lry@ubuntu:~/codes/fs$ stat cool_link
  File: cool_link
  Size: 5368709120      Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 2883778     Links: 2
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     lry)   Gid: ( 1000/     lry)
Access: 2021-10-02 11:00:22.490656951 +0800
Modify: 2021-10-02 10:59:00.306109455 +0800
Change: 2021-10-02 15:09:01.247004439 +0800

符号链接symbolic link

类似Windows下的快捷方式。

lry@ubuntu:~/codes/fs$ stat cool
  File: cool
  Size: 5368709120      Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 2883778     Links: 2
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     lry)   Gid: ( 1000/     lry)
Access: 2021-10-02 11:00:22.490656951 +0800
Modify: 2021-10-02 10:59:00.306109455 +0800
Change: 2021-10-02 15:09:01.247004439 +0800
 Birth: -
lry@ubuntu:~/codes/fs$ ln -s cool cool_s_l
lry@ubuntu:~/codes/fs$ stat cool
  File: cool
  Size: 5368709120      Blocks: 8          IO Block: 4096   regular file
Device: 805h/2053d      Inode: 2883778     Links: 2
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     lry)   Gid: ( 1000/     lry)
Access: 2021-10-02 11:00:22.490656951 +0800
Modify: 2021-10-02 10:59:00.306109455 +0800
Change: 2021-10-02 15:09:01.247004439 +0800
 Birth: -
lry@ubuntu:~/codes/fs$ stat cool_s_l
  File: cool_s_l -> cool
  Size: 4               Blocks: 0          IO Block: 4096   symbolic link
Device: 805h/2053d      Inode: 2883783     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/     lry)   Gid: ( 1000/     lry)
Access: 2021-10-02 15:19:19.744663266 +0800
Modify: 2021-10-02 15:18:55.340616457 +0800
Change: 2021-10-02 15:18:55.340616457 +0800
 Birth: -

函数link unlink

man 2 link

NAME
       link, linkat - make a new name for a file
SYNOPSIS
       #include <unistd.h>
       int link(const char *oldpath, const char *newpath);

man 2 unlink

NAME
       unlink, unlinkat - delete a name and possibly the file it refers to
SYNOPSIS
       #include <unistd.h>
       int unlink(const char *pathname);

函数remove

man remove

NAME
       remove - remove a file or directory
SYNOPSIS
       #include <stdio.h>
       int remove(const char *pathname);

函数rename

NAME
       rename, renameat, renameat2 - change the name or location of a file
SYNOPSIS
       #include <stdio.h>
       int rename(const char *oldpath, const char *newpath);

时间utime

更改文件的最后访问时间和最后修改时间

NAME
       utime, utimes - change file last access and modification times
SYNOPSIS
       #include <sys/types.h>
       #include <utime.h>
       int utime(const char *filename, const struct utimbuf *times);
      
	
	       struct utimbuf {
               time_t actime;       /* access time */
               time_t modtime;      /* modification time */
           };

假根技术chroot
chdir、fchdir可以突破假根技术,chroot穿越

chdir
fchdir
getcwd

函数glob();

opendir();
closedir();
readdir();
rewinddir();
seekdir();
telldir();
man glob

NAME
       glob, globfree - find pathnames matching a pattern, free memory from glob()
SYNOPSIS
       #include <glob.h>
       int glob(const char *pattern, int flags,
                int (*errfunc) (const char *epath, int eerrno),
                glob_t *pglob);
       void globfree(glob_t *pglob);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值