首页 > 其他分享 >学习笔记4

学习笔记4

时间:2023-09-30 10:11:05浏览次数:41  
标签:char 文件 int 笔记 学习 include inode block

苏格拉底挑战


第七章 文件操作

一.知识点归纳

(一)文件操作级别

文件操作分为五个级别,按照从低到高的顺序排列如下:

1.硬件级别:

硬件级别的文件操作包括:

  • fdisk:将硬盘、U盘或SDC盘分区。
  • mkfs:格式化磁盘分区,为系统做好准备。
  • fsck:检查和维修系统。
  • 碎片整理:压缩文件系统中的文件。

2.操作系统内核中的文件系统函数

每个操作系统内核均可为基本文件操作提供支持。下文列出了类Unix系统内核中的一些函数,其中前缀 k 表示内核函数。

kmount(), kumount()		(mount/umount file systems)
kmkdir(), krmdir()		(make/remove directory)
kchdir(), kgetcwd()		(change directory, get CWD pathname)
klink(),  kunlink()		(hard link/unlink files)
kchmod(), kchown(), kutime()	(change r|w|x permissions,owner,time)
kcreat(), kopen()		(create/open file for R,W,RW,APPEND)
kread(),  kwrite()		(read/write opened files)
klseek(), kclose()		(lseek/close file descriptors)
ksymlink(), kreadlink()		(create/read symbolic link files)
kstat(),  kfstat(), klstat()	(get file status/information)
kopendir(), kreaddir()		(open/read directories)

3.系统调用

用户模式程序使用系统调用来访问内核函数。例如,下面的程序可读取文件的第二个1024字节。

#include<fcntl.h>
int main(int argc, char *agrv[])
{
	int fd, n;
	char buf[1024];
	if((fd = open(argv[1], O_RDONLY))<0)
		exit(1);
	lseek(fd, 1024, SEEK_SET);
	n = read(fd, buf, 1024);
	close(fd);
}

4.I/O库函数

I/O库函数包括:

FILE mode I/0: fopen(),fread(); fwrite(),fseek(),fclose(),fflush()
char mode I/0: getc(), getchar(),ugetc(); putc(),putchar()
line mode I/0: gets(), fgets(); puts(), fputs()
formatted I/0: acanf(),fscanf(),sscanf(); printf(),fprintf(),sprintf()

5.用户命令

用户可以使用 Unix/Linux 命令来执行文件操作,而不是编写程序。用户命令的示例如下:

mkdir, rmdir, cd, pwd, ls, link, unlink, rm, cat, cp, mv, chmod, etc.

每个用户命令实际上是一个可执行程序(cd除外),通常会调用库I/O函数,而库I/O函数再发出系统调用来调用相应的内核函数。用户命令的处理顺序为:

Command => Library I/O function => System call => Kernel Function
或
Command =========================> System call => Kernel Function

(二)文件I/O操作

(三)低级别文件操作

1.分区

在 Linux 下,创建一个名为 mydisk 的虚拟磁盘映像文件。

dd if=/dev/zero of=mydisk bs=1024 count=1440

dd 是将一个1440(1KB)个0字节块写入目标文件 mydisk 的程序。我们选择 count=1440,因为它是旧软盘的 1KB 字节块的数量。必要时,可指定更大的库编号。

2.格式化分区

格式:

mkfs -t TYPE [-b bsize] device nblocks

假设是 EXT2/3 文件系统,它是 Linux 的默认文件系统。因此,

mkfs -t ext2 vdisk 1440  或  mke2fs vdisk 1440
sudo mount -o loop vdisk /mnt
sudo umount /mnt  或  sudo umount vdisk

3.挂载分区

#(1)用dd命令创建一个虚拟磁盘映像
dd if=/dev/zero of=mydisk bs=1024 count=32768
#(2)在vdisk上运行fdisk来创建一个分区P1
fdisk vdisk
#(3)使用以下扇区数在vdisk的分区1上创建一个循环设备
losetup -o $(expr 2048 \* 512) --sizelimit $(expr 65535 \* 512) /dev/loop1
vdisk
losetup -a
#(4)格式化/dev/loop1,它是一个EXT2文件系统
mke2fs -b 4096 /dev/loop1 7936
#(5)挂载循环设备
mount /dev/loop1 /mnt
#(6)访问作为文件系统一部分的挂载系统
(cd /mnt; mkdir bin boot dev etc user)
#(7)设备使用完毕后,将其卸载
umount /mnt
#(8)循环设备使用完毕后,通过以下命令将其断开
losetup -d /dev/loop1

(四)EXT2文件系统简介

在 Linux 下,我们可以创建一个包含简单 EXT2 文件系统的虚拟磁盘,如下文所示:

dd if=/dev/zero of=mydisk bs=1024 count=1440
mke2fs -b 1024 mydisk 1440

image
image

  • Block#0:引导块
    • B0是引导块(Boot Block),文件系统不会使用它。它用于容纳从磁盘引导操作系统的引导程序。
  • Block#1:超级块
    • 超级块(Super Block)描述整个分区的文件系统信息,如inode/block的大小、总量、使用量、剩余量,以及文件系统的格式与相关信息。超级块在每个块组的开头都有一份拷贝(第一个块组必须有,后面的块组可以没有)。
    • 超级块记录的信息有:
      1. block 与 inode 的总量(分区内所有Block Group的block和inode总量);
      2. 未使用与已使用的 inode / block 数量;
      3. block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128 bytes);
      4. filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息;
      5. 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1 。
  • Block#2:块组描述符块
    • 块组描述符块(GD)由很多块组描述符组成,整个分区分成多个块组就对应有多少个块组描述符。
    • 每个块组描述符存储一个块组的描述信息,如在这个块组中从哪里开始是inode Table,从哪里开始是Data Blocks,空闲的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有一份拷贝。
  • Block#8:块位图
    • 块位图(Block Bitmap)用来描述整个块组中哪些块已用哪些块空闲。块位图本身占一个块,其中的每个bit代表本块组的一个block,这个bit为1代表该块已用,为0表示空闲可用。假设格式化时block大小为1KB,这样大小的一个块位图就可以表示1024*8个块的占用情况,因此一个块组最多可以有10248个块。
  • Block#9:索引节点位图
    • inode位图(inode Bitmap)和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用。 Inode bitmap的作用是记录block group中Inode区域的使用情况,Ext文件系统中一个block group中可以有16384个Inode,代表着这个Ext文件系统中一个block group最多可以描述16384个文件。
  • Block#10:索引(开始)节点块
    • inode表(inode Table)由一个块组中的所有inode组成。一个文件除了数据需要存储之外,一些描述信息也需要存储,如文件类型,权限,文件大小,创建、修改、访问时间等,这些信息存在inode中而不是数据块中。inode表占多少个块在格式化时就要写入块组描述符中。 在Ext2/Ext3文件系统中,每个文件在磁盘上的位置都由文件系统block group中的一个Inode指针进行索引,Inode将会把具体的位置指向一些真正记录文件数据的block块,需要注意的是这些block可能和Inode同属于一个block group也可能分属于不同的block group。我们把文件系统上这些真实记录文件数据的block称为Data blocks。

第八章 使用系统调用进行文件操作

一.知识点归纳

(一)系统调用

在操作系统中,进程以两种不同的模式运行,即内核模式和用户模式,简称 Kmode 和 Umode。在 Umode 中,进程的权限非常有限。它不能执行任何需要特殊权限的操作。特殊权限的操作必须在 Kmode 下执行。系统调用(简称 syscall)是一种允许进程进入 Kmode 以执行 Umode 不允许操作的机制。

(二)简单的系统调用

  • access:检查对某个文件的权限
int access(char *pathname, int mode);
  • chdir:更改目录
int chdir(const char *path);
  • chmod:更改某个文件的权限
int chmod(char *path, mode_t mode);
  • chown:更改文件所有人
int chown(char *name, int uid, int gid);
  • chroot:将(逻辑)根目录更改为路径名
int chroot(char *pathname);
  • getcwd:获取 CWD 的绝对路径名
char *getcwd(char *buf, int size);
  • mkdir:创建目录
int mkdir(char *pathname, mode_t mode);
  • rmdir:移除目录(必须为空)
int rmdir(char *pathname);
  • link:将新文件硬链接到旧文件
int link(char *oldPath, int *newPath);
  • unlink:取消某个文件的链接;如果文件的链接数为0,则删除文件
int unlink(char *pathname);
  • symlink:创建一个符号链接
int symlink(char *target, char *newpath);
  • rename:更改文件名称
int rename(char *oldPath, int *newPath);
  • utime:更改文件的访问和修改时间
int utime(char *pathname, struct utimebuf *time);

以下系统调用需要超级用户权限。

  • mount:将文件系统添加到挂载点目录上
int mount(char *specialfile, char *mountDir);
  • umount:分离挂载的文件系统
int umount(char *dir);
  • mknod:创建特殊文件
int mknod(char *path, int mode, int device);

(三)常用的系统调用

  • stat:获取文件状态信息
int stat(char *filename, struct stat *buf);
int fstat(char filedes, struct stat *buf);
int lstat(char *filename, struct stat *buf);
  • open:打开一个文件进行读、写、追加
int open(char *file, int flags, int mode);
  • close:关闭打开的文件描述符
int read(int fd);
  • read:读取打开的文件描述符
int read(int fd, char buf[], int count);
  • write:写入打开的文件描述符
int write(int fd, char buf[], int count);
  • lseek:重新定位文件描述符的读/写偏移量
int lseek(int fd, char offset, int whence);
  • dup:将文件描述符复制到可用的最小描述符编号中
int dup(int oldfd);
  • dup2:将 oldfd 复制到 newfd 中,如果 newfd 已打开,先将其关闭
int dup2(int oldfd, int newfd);
  • link:将新文件硬链接到旧文件
int link(char *oldPath, int *newPath);
  • unlink:取消某个文件的链接;如果文件的链接数为0,则删除文件
int unlink(char *pathname);
  • symlink:创建一个符号链接
int symlink(char *target, char *newpath);
  • readlink::读取符号链接文件的内容
int readlink(char *path, char *buf, int bufsize);
  • umask:设置文件创建掩码;文件权限为(mask & ~umask)
int umask(int umask);

(四)链接文件

1.硬链接文件

硬链接:命令

ln oldpath newpath

创建从 newpath 到 oldpath 的硬链接,对应的系统调用为:

link(char *oldPath, int *newPath)

2.符号链接文件

软连接:命令

ln -s oldpath newpath	# ln command with the -s flag

创建从 newpath 到 oldpath 的软链接或符号链接,对应的系统调用为:

symlink(char *target, char *newpath)

二.问题与解决思路

三.实践内容与截图

(一)mkdir、chdir、getcwd 系统调用

#include<stdio.h>
#include<errno.h>
int main()
{
  char buf[256],*s;
  int r;
  r=mkdir("newdir",0766);//mkdir syscall
  if(r<0)
    printf("errno=%d : %s\n",errno,strerror(errno));
  r=chdir("newdir");//cd into newdir
  s=getcwd(buf,256);//get CWD string into buf[]
  printf("CWD = %s\n",s);
}

image

(二)ls程序

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>

int main(int argc,char * argv[]){
    if(argc<2){
        printf("%s need filename\n",argv[0]);
        return -1;
    }
    struct stat st;
    int ret=stat(argv[1],&st);
    if(ret==-1){
        perror("stat");
        return -1;
    }
    char perms[11]={0}; 

    switch (st.st_mode & S_IFMT){
        case S_IFLNK:
            perms[0]='l';
            break;
        case S_IFDIR:
            perms[0]='d';
            break;
        case S_IFREG:
            perms[0]='-';
            break;
        case S_IFBLK:
            perms[0]='b';
            break;
        case S_IFCHR:
            perms[0]='c';
            break;
        case S_IFSOCK:
            perms[0]='s';
            break;
        case S_IFIFO:
            perms[0]='p';
            break;
        default:
            perms[0]='?';
            break;
    }
    
    perms[1]=(st.st_mode & S_IRUSR) ? 'r':'-';
    perms[2]=(st.st_mode & S_IWUSR) ? 'w':'-';
    perms[3]=(st.st_mode & S_IXUSR) ? 'x':'-';
    perms[4]=(st.st_mode & S_IRGRP) ? 'r':'-';
    perms[5]=(st.st_mode & S_IWGRP) ? 'w':'-';
    perms[6]=(st.st_mode & S_IXGRP) ? 'x':'-';
    perms[7]=(st.st_mode & S_IROTH) ? 'r':'-';
    perms[8]=(st.st_mode & S_IWOTH) ? 'w':'-';
    perms[9]=(st.st_mode & S_IXOTH) ? 'x':'-';

    int linkNum=st.st_nlink;

    char * fileUser = getpwuid(st.st_uid)->pw_name;
    char * fileGrp = getgrgid(st.st_gid)->gr_name;
    long int fileSize = st.st_size;
    char * time = ctime(&st.st_mtime);

    char mtime[512]={0};
    strncpy(mtime,time,strlen(time)-1);

    char buf[1024];
    sprintf(buf,"%s %d %s %s %ld %s %s",perms,linkNum,fileUser,fileGrp,fileSize,mtime,argv[1]);
    printf("%s\n",buf);
    return 0;
}

(三)显示文件内容(cat 命令)

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

#define BLKSIZE 4096
int main(int argc, char *argv[])
{
	int fd, i, m, n;
	char buf[BLKSIZE], dummy;
	if(argc>1)
	{
		fd = open(argv[1], O_RDONLY);
		if(fd < 0)
			exit(1);
	}
	while(n = read(fd, buf, BLKSIZE))
	{
		m = write(1, buf, n);
	}
}

(四)复制文件(cp sec dest 命令)

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

#define BLKSIZE 4096
int main(int argc, char *argv[])
{
	int fd, gd, n, total=0;
	char buf[BLKSIZE];
	if(argc<3)
		exit(1);
	if((fd = (open(argv[1], O_RDONLY)) < 0))
		exit(2);
	if((gd = open(argv[2], O_WRONLY|O_CREAT)) < 0)
		exit(3); 
	while(n = read(fd, buf, BLKSIZE))
	{
		write(gd, buf, n);
		total += n;
	}
	printf("total bytes copied=%d\n", total);
	close(fd);
	close(gd);
}

标签:char,文件,int,笔记,学习,include,inode,block
From: https://www.cnblogs.com/hosf/p/17737644.html

相关文章

  • 高级系统架构师学习(九)数据库系统
    一、数据库概述数据库模式三级模式:外模式:视图模式(也称为概念模式):数据库表内模式:物理文件两层映像:两层映像可以保证数据库中的数据具有较高的逻辑独立性和物理独立性。外模式-模式映像模式-内模式映像物理独立性:即数据库的内模式发生改变时,应用程序不需要改变。......
  • 大模型强化学习——PPO项目实战
    【PPO算法介绍】PPO(Proximal Policy Optimization)是一种强化学习算法,它的目标是找到一个策略,使得根据这个策略采取行动可以获得最大的累积奖励。PPO的主要思想是在更新策略时,尽量让新策略不要偏离旧策略太远。这是通过在目标函数中添加一个额外的项来实现的,这个额外的项会惩罚......
  • Pyinstaller 使用笔记
    Pyinstaller用于将Python应用和连同其所需依赖打包在一起,使其可以在不安装Python解释器的相同操作系统的计算机上运行。Pyinstaller库支持Python3.8及其更新版本,可以正确地打包较大Python包,如 numpy,matplotlib,PyQt,wxPython等等。需要注意,Pyinstaller不是一......
  • 从小工到专家阅读笔记(二)
    4.足够好的软件所有设计出的系统都必须满足其用户的需求.才能取得成功.我们只是在宣扬、给用户以机会.让他们参与决定你的软件是否能让他们满意。“使质量成为需求”,很多时候都是开发人员在进行对于质量的评估,我们对质量要求低的话,交付时就会出现很多问题,我们对质量要求高,又会很大......
  • 《信息安全系统设计与实现》第四周学习笔记
    一、课程内容第七章学习文件操作级别1、硬件级别fdiskmkfsfsck碎片整理2、操作系统内核中的文件系统函数3、系统调用4、I/O库函数5、用户命令6、sh脚本低级别的文件操作中的常用函数:打开和关闭文件:open():打开文件并返回文件描述符。close():关闭文件。读写文件:......
  • gcc学习
    GCC自动识别的常用扩展名以c语言的方式编译当前文件(即为demo)gcc-xcdemo......
  • UCB-Sysadmin 笔记
    LinuxSystemAdministrationDecalAcoursecoveringthebasicsofsettingupandadministeringaproduction-qualityLinuxserverenvironment.Lab1找出隐藏文件ls-a连接输出,然后删除文件catnaming_is_hard*|xargs#stanford>berkeleyrm-rfn......
  • 《梦断代码》读书笔记02
    1、对该项目的人的认识不得不承认的一点是,这个项目的基础特别棒,在万众瞩目下开启开发的旅程,历时七年,在完工之际,已经没有人为之喝彩;项目团队人人都很优秀,在我眼里,他们不仅仅是久远时光里的一个出名的项目团队,他们还是独一无二的编程“疯子”,他们热爱编程、享受编程,不屑于将自己......
  • 《Java编程思想第四版》学习笔记32--关于static字段的序列化
    //:CADState.java//Savingandrestoringthestateofa//pretendCADsystem.importjava.io.*;importjava.util.*;abstractclassShapeimplementsSerializable{publicstaticfinalintRED=1,BLUE=2,GREEN=3;privateintxPos,yPos,dimension;p......
  • python,机器学习,代码,三种方法,拟合,物料的冷却规律:温度Y=f(时间X,物料类型A,冷却方
    python,机器学习,代码,三种方法,拟合,物料的冷却规律:温度Y=f(时间X,物料类型A,冷却方式B)+其他因素理解你的问题,你似乎正在探讨如何使用机器学习方法对物料的冷却规律进行拟合,考虑到时间、物料类型、冷却方式以及其他因素。在这里,我将提供一个基本的框架,介绍三种常见的机器学习方......