当前位置: 首页 > news >正文

淘宝客网站怎么做视频wordpress买域名

淘宝客网站怎么做视频,wordpress买域名,最火的做网站源码语言,php网站后台忘记密码目录 前言 一、C语言中文件IO操作 1.文件的打开方式 2.fopen#xff1a;打开文件 3.fread#xff1a;读文件 4.fwrite:写文件 二、系统文件I/O 1.系统调用open、read、write 2.文件描述符fd 3.文件描述符的分配规则 4.重定向 5.缓冲区 6.理解文件系统 磁盘 磁盘…目录 前言 一、C语言中文件IO操作 1.文件的打开方式 2.fopen打开文件  3.fread读文件  4.fwrite:写文件 二、系统文件I/O 1.系统调用open、read、write 2.文件描述符fd 3.文件描述符的分配规则 4.重定向 5.缓冲区 6.理解文件系统 磁盘 磁盘的逻辑抽象 磁盘分区  磁盘格式化 EXT2文件系统的存储方案 软硬链接 软链接 硬链接 软硬链接的区别 文件的三个时间ACM时间 三、动态库和静态库 1.动态库和静态库的概念 2.如何生成静态库 3.如何去使用一个静态库  4.如何生成一个动态库 5.如何去使用一个动态库  前言 一、C语言中文件IO操作 1.文件的打开方式 r 只读方式打开文件指针指向文件的首位置r 读写方式打开文件指针指向文件的首位置w 只写方式打开清空文件内容如果文件不存在则创建文件文件指针指向文件的首位置w 读写方式打开文件不存在则创建文件如果文件存在则清空原来内容文件指针指向文章的首位置a 以追加写的方式打开写到文件的结尾处文件不存在则创建文件文件指针指向文件的末尾位置a 以读和追加写的方式打开文件不存在则创建文件如果文件存在则从文件的末尾位置开始追加 2.fopen打开文件  3.fread读文件  4.fwrite:写文件 二、系统文件I/O 1.系统调用open、read、write int open(const char *pathname, int flags, mode_t mode);参数 和 返回值 成功:返回一个文件描述符失败:返回-1 ssize_t read(int fd, void *buf, size_t count); 参数和返回值 文件描述符fd表示要读取数据的文件。缓冲区buf用于存储读取数据的缓冲区。要读取的字节数count表示要读取的字节数。 需要注意的是在实际编程中通常会使用循环来读取大文件中的数据每次读取的字节数为缓冲区的大小。 成功读取到的字节数表示成功读取到的字节数。失败-1表示发生错误错误原因可以通过errno查看。 ssize_t write(int fildes, const void *buf, size_t nbyte); 参数 和 返回值 fildes文件描述符标识要写入的文件或设备。buf指向要写入数据的缓冲区。nbytes要写入的字节数。 成功写入的字节数表示成功写入的字节数。失败-1表示出现错误具体的错误信息可以通过errno来获取。 2.文件描述符fd 文件是由进程运行时打开的一个进程可以打开多个文件而系统当中又存在大量进程也就是说在系统中任何时刻都可能存在大量已经打开的文件。因此操作系统务必要对这些已经打开的文件进行管理操作系统会为每个已经打开的文件创建各自的struct file结构体然后将这些结构体以双链表的形式连接起来之后操作系统对文件的管理也就变成了对这张双链表的增删查改等操作。而为了区分已经打开的文件哪些属于特定的某一个进程我们就还需要建立进程和文件之间的对应关系。 进程和文件之间的对应关系是如何建立的 进程 task_struct 当中有一个指针该指针指向一个名为files_struct的结构体在该结构体当中就有一个名为fd_array的指针数组该数组的下标就是我们所谓的文件描述符。 当进程打开 log.txt 文件时我们需要先将该文件从磁盘当中加载到内存形成对应的struct file将该struct file连入文件双链表并将该结构体的首地址填入到fd_array数组当中下标为3的位置使得fd_array数组中下标为3的指针指向该struct file最后返回该文件的文件描述符给调用进程即可。 文件描述符 fd 本质就是数组的下标  因此我们只要有某一文件的文件描述符就可以找到与该文件相关的文件信息进而对文件进行一系列输入输出操作。 为啥我们打开文件文件描述符是从 3 开始的012 哪去了  0就是标准输入流对应键盘1就是标准输出流对应显示器2就是标准错误流也是对应显示器。 而键盘和显示器都属于硬件属于硬件就意味着操作系统能够识别到当某一进程创建时操作系统就会根据键盘、显示器、显示器形成各自的struct file将这3个struct file连入文件双链表当中并将这3个struct file的地址分别填入fd_array数组下标为0、1、2的位置至此就默认打开了标准输入流、标准输出流和标准错误流。 操作系统为啥要默认打开0stdin1stdout2stderr 就是为了让程序员进行默认输入输出 如何理解一切皆文件 3.文件描述符的分配规则 我们先做几个小实验 #include iostream#include unistd.h using namespace std;int main() {char buf[1024];ssize_t s read(0, buf, 1024);if (s 0){buf[s] 0;cout echo# buf endl;}return 0; } 我们发现我们输入什么就会给我们打印什么 我们并没有打开0、1号文件说明0、1号文件是默认打开的。 #include stdio.h #include sys/stat.h #include sys/types.h #include fcntl.h int main() {umask(0);int fd1 open(log1.txt, O_RDONLY | O_CREAT, 0666);int fd2 open(log2.txt, O_RDONLY | O_CREAT, 0666);int fd3 open(log3.txt, O_RDONLY | O_CREAT, 0666);int fd4 open(log4.txt, O_RDONLY | O_CREAT, 0666);int fd5 open(log5.txt, O_RDONLY | O_CREAT, 0666);printf(fd1:%d\n, fd1);printf(fd2:%d\n, fd2);printf(fd3:%d\n, fd3);printf(fd4:%d\n, fd4);printf(fd5:%d\n, fd5);return 0; }可以看到这五个文件获取到的文件描述符都是从3开始连续递增的这很好理解因为文件描述符本质就是数组的下标而当进程创建时就默认打开了标准输入流、标准输出流和标准错误流也就是说数组当中下标为0、1、2的位置已经被占用了所以只能从3开始进行分配。  若我们在打开这五个文件前先关闭文件描述符为0的文件此后文件描述符的分配又会是怎样的呢 可以看到第一个打开的文件获取到的文件描述符变成了0而之后打开文件获取到的文件描述符还是从3开始依次递增的。 我们可以得出下面两个结论 进程默认已经打开了012文件描述符的分配规则找到当前没有被使用的最小下标作为新文件的文件描述符 4.重定向 我们先来做一个小实验 #include iostream #include cstdlib #include cstring#include unistd.h #include sys/types.h #include sys/stat.h #include fcntl.h using namespace std;int main() {// 输出重定向close(1);int fd open(myfile, O_WRONLY|O_CREAT, 00644);if (fd 0){cerr open;return 1;}cout fd: fd endl;// cout cout- fd: cout-_fileno endl;flush(cout);return 0; } 此时我们发现本来应该输出在显示器上的的内容输出到了文件myfile中我们把这种现象叫做输出重定向 那么为啥本来应该输出在显示器上的的内容输出到了文件myfile中 #include iostream #include cstdlib #include cstring #include cstdio#include unistd.h #include sys/types.h #include sys/stat.h #include fcntl.h using namespace std;int main() {// 输入重定向close(0);int fd open(myfile, O_RDONLY);if (fd 0){cerr open endl;return 1;}char buf[1024];fread(buf, 1, sizeof(buf), stdin);printf(%s\n,buf);return 0; } 此时我们发现本来应该等待我们在键盘输入结果直接把文件myfile中的内容打印出来了我们把这种现象叫做输入重定向 原因和上面类似本质就是上层fd不变底层fd指向的内容发生变化 但是我们这样实现重定向太麻烦了重定向本质就是上层fd不变底层fd指向的内容发生变化那么我们就可以直接将3的内容直接覆盖到1中去那么有没有文件描述符级别的数组内容的拷贝有函数dup2 int dup2(int oldfd, int newfd); 参数 和 返回值  oldfd要复制的文件描述符。newfd指定新的文件描述符。 成功时返回新的文件描述符。失败时返回 -1并设置errno来表示错误原因。 我们使用dup2来实现一个输入重定向 #include cstdlib #include cstring #include cstdio#include unistd.h #include sys/types.h #include sys/stat.h #include fcntl.h using namespace std;int main() {// 输入重定向int fd open(myfile, O_RDONLY);dup2(fd, 0);if (fd 0){cerr open endl;return 1;}char buf[1024];fread(buf, 1, sizeof(buf), stdin);printf(%s\n,buf);return 0; } 我们发现确实可以实现输入重定向 5.缓冲区 缓冲区是什么 缓冲区是一部分内存 为什么要有缓冲区 我来给大家讲解一个小故事在广东读大学的小明有一个在北京读大学的好朋友小光最近小光快要生日了小明打算送一个生日礼物给小光现在小明有两个选择一是自己骑一个车送给小光二是直接下楼送到老鸟驿站再由老鸟驿站送过去。如果你是小明你会如何选择呢 我肯定选择直接下楼送到老鸟驿站。因为把礼物送到老鸟驿站后我的任务就完成了。虽然老鸟驿站还是要把礼物送过去。时间没变但是我不用去送了好处一提高了我的效率 礼物到了老鸟驿站后驿站会直接将礼物直接送去北京吗显然不会驿站会累计一部分都是北京的包裹在一起送过去。好处二提高了发送的效率 驿站就相当于缓冲区 缓冲区提高了使用者的效率因为有了缓冲区的存在我们可以积累一部分统一发送提高了发送的效率总的来说缓冲区就是提高了效率 因为缓冲区可以暂存数据所以必定有一定的刷新方式就像驿站存储到一定的数量再发货 无缓冲立即刷新行缓冲一行满了就刷新全缓冲缓冲区满了再刷新 显示器行缓冲磁盘文件全缓冲 特殊情况 强制刷新进程退出的时候一般要刷新 我们来做一个实验 #include stdio.h #include string.h #include unistd.hint main() {fprintf(stdout, C: hello fprintf\n);printf(C: hello printf\n);fputs(C: hello fputs\n, stdout);const char *str system call : hello write\n;write(1, str, strlen(str));fork();return 0; } 运行结果 如果我们对进程进行输入重定向发现除了write外所有的都打印了两次 这是因为什么呢 我们直接在显示器上打印的时候行刷新输出字符串时都有 \nfork之前的数据都已经刷新了我们重定向到myfile本质是向磁盘文件写入。全缓冲 此时我们使用printf和fputs函数打印的数据都打印到了C语言自带的缓冲区当中之后当我们使用fork函数创建子进程时。由于进程间具有独立性当进程退出的时候父进程或是子进程对要刷新缓冲区内容时本质就是对父子进程共享的数据进行了修改此时就需要对数据进行写时拷贝至此缓冲区当中的数据就变成了两份一份父进程的一份子进程的所以重定向到myfile文件当中printf和puts函数打印的数据就有两份。但由于write函数是系统接口我们可以将write函数看作是没有缓冲区的因此write函数打印的数据就只打印了一份。 这个缓冲区是谁提供的用户缓冲区 实际上这个缓冲区是C语言自带的如果说这个缓冲区是操作系统提供的那么printf、fputs和write函数打印的数据重定向到文件后都应该打印两次。 这个缓冲区在哪里 我们常说printf是将数据打印到stdout里面而stdout就是一个FILE*的指针在FILE结构体当中还有一大部分成员是用于记录缓冲区相关的信息的。 //缓冲区相关 /* The following pointers correspond to the C streambuf protocol. */ /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putbackget area. */ char* _IO_write_base; /* Start of put area. */ char* _IO_write_ptr; /* Current put pointer. */ char* _IO_write_end; /* End of put area. */ char* _IO_buf_base; /* Start of reserve area. */ char* _IO_buf_end; /* End of reserve area. */ /* The following fields are used to support backing up and undo. */ char *_IO_save_base; /* Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backup area */ char *_IO_save_end; /* Pointer to end of non-current get area. */也就是说这里的缓冲区是由C语言提供在FILE结构体当中进行维护的FILE结构体当中不仅保存了对应文件的文件描述符fd还保存了用户缓冲区的相关信息。 FILE是C语言封装的一个结构体 因为库函数是对系统调用接口的封装本质上访问文件都是通过文件描述符fd进行访问的所以C库当中的FILE结构体内部必定封装了文件描述符fd。 首先我们在/usr/include/stdio.h头文件中可以看到下面这句代码也就是说FILE实际上就是struct _IO_FILE结构体的一个别名。 typedef struct _IO_FILE FILE;而我们在/usr/include/libio.h头文件中可以找到struct _IO_FILE结构体的定义在该结构体的众多成员当中我们可以看到一个名为_fileno的成员这个成员实际上就是封装的文件描述符。 struct _IO_FILE {int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ #define _IO_file_flags _flags//缓冲区相关/* The following pointers correspond to the C streambuf protocol. *//* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */char* _IO_read_ptr; /* Current read pointer */char* _IO_read_end; /* End of get area. */char* _IO_read_base; /* Start of putbackget area. */char* _IO_write_base; /* Start of put area. */char* _IO_write_ptr; /* Current put pointer. */char* _IO_write_end; /* End of put area. */char* _IO_buf_base; /* Start of reserve area. */char* _IO_buf_end; /* End of reserve area. *//* The following fields are used to support backing up and undo. */char *_IO_save_base; /* Pointer to start of non-current get area. */char *_IO_backup_base; /* Pointer to first valid character of backup area */char *_IO_save_end; /* Pointer to end of non-current get area. */struct _IO_marker *_markers;struct _IO_FILE *_chain;int _fileno; //封装的文件描述符 #if 0int _blksize; #elseint _flags2; #endif_IO_off_t _old_offset; /* This used to be _offset but its too small. */#define __HAVE_COLUMN /* temporary *//* 1column number of pbase(); 0 is unknown. */unsigned short _cur_column;signed char _vtable_offset;char _shortbuf[1];/* char* _save_gptr; char* _save_egptr; */_IO_lock_t *_lock; #ifdef _IO_USE_OLD_IO_FILE };C语言当中的函数究竟在做什么 fopen函数在上层为用户申请FILE结构体变量并返回该结构体的地址(FILE*)在底层通过系统接口open打开对应的文件得到文件描述符fd并把fd填充到FILE结构体当中的_fileno变量中至此便完成了文件的打开操作。 而C语言当中的其他文件操作函数比如fread、fwrite、fputs、fgets等都是先根据我们传入的文件指针找到对应的FILE结构体然后在FILE结构体当中找到文件描述符最后通过文件描述符对文件进行的一系列操作。 6.理解文件系统 磁盘 磁盘的基本特征 磁盘是一种存储设备主要用于计算机系统中数据的存储。 它通常由磁性材料制成的盘片组成通过磁头在盘片上读写数据。磁盘可以分为硬盘和软盘等类型具有较大的存储容量可以长期保存数据。 一个磁盘有很多盘片一个盘片有很多的同心磁道一圈磁道有很多的扇形的扇区 扇区是磁盘的最小的存储单元 ------- 512字节0.5kb 如果我想向一个扇区进行写入我应该如何去寻址 柱面号确定扇区所在的柱面位置。磁头号哪一盘片确定读写头所在的磁头位置。扇区号确定具体要写入的扇区编号。 通过以上三个步骤最终确定信息在磁盘的读写位置。柱面号Cylinder、磁头号Head和扇区号Sector简称为CHS定位法。 磁盘的逻辑抽象 首先我们必须将磁盘想象成一个线性的存储介质想想磁带当磁带被卷起来时其就像磁盘一样是圆形的但当我们把磁带拉直后其就是线性的。 这样对磁盘的管理就变成了对数组的管理 磁盘通常被称为块设备一般以扇区为单位一个扇区的大小通常为512字节。我们若以大小为512G的磁盘为例该磁盘就可被分为十亿多个扇区。 操作系统可以按照扇区为单位进行存取也可以基于文件系统按照文件块为单位进行存取 八个扇区为一个文件块4kb我们会以一个文件块来存储文件 所以只要知道文件的起始地址就可以知道整个文件我们把这种寻址的方式方法叫做LBA寻址法 LBA 地址的工作原理如下 连续编号LBA 对磁盘上的每个扇区进行连续编号从 0 开始递增。转换当需要访问某个扇区时系统会将 LBA 地址转换为对应的CHS地址物理磁盘结构柱面、磁头、扇区信息。寻址通过这种转换磁盘控制器可以准确地找到要访问的扇区并进行数据读写操作。 这样的方式使得磁盘访问更加灵活和高效不受磁盘物理结构的限制。 这样对存储设备的管理在操作系统层面就转换成为了对数组的增删查改 磁盘分区  磁盘通常被称为块设备一般以扇区为单位一个扇区的大小通常为512字节。我们若以大小为500G的磁盘为例该磁盘就可被分为十亿多个扇区。 计算机为了更好的管理磁盘于是对磁盘进行了分区。磁盘分区就是使用分区编辑器在磁盘上划分几个逻辑部分盘片一旦划分成数个分区不同的目录与文件就可以存储进不同的分区分区越多就可以将文件的性质区分得越细按照更为细分的性质存储在不同的地方以管理文件例如在Windows下磁盘一般被分为C盘和D盘、E盘、F盘等等。 磁盘格式化 当磁盘完成分区后我们还需要对磁盘进行格式化。磁盘格式化是指对磁盘或磁盘中的分区进行初始化的一种操作。简单来说磁盘格式化就是对分区后的各个区域写入对应的管理信息。 在格式化过程中磁盘上原有的数据会被清除同时会建立文件系统为存储数据做好准备。不同的文件系统有不同的特点和适用场景。 常见的文件系统 EXT2/EXT3/EXT4Linux 系统中常用的文件系统。APFS苹果的新一代文件系统。ReFS微软推出的新一代文件系统。 EXT2文件系统的存储方案 计算机为了更好的管理磁盘会对磁盘进行分区。而对于每一个分区来说分区的头部会包括一个启动块(Boot Block)对于该分区的其余区域EXT2文件系统会根据分区的大小将其划分为一个个的块组(Block Group)。 注意 启动块的大小是确定的而块组的大小是由格式化的时候确定的并且不可以更改。  其次每个组块都有着相同的组成结构每个组块都由超级块(Super Block)、块组描述符表(Group Descriptor Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)以及数据表(Data Block)组成。但是其中超级块(Super Block)并不是每一块组都有。通常超级块会在多个块组中进行备份以提高文件系统的可靠性。这样可以在出现问题时从备份中恢复超级块的信息。 inode表(inode Table) inode表记录了文件和目录的相关信息如文件的属性如文件类型、权限、所有者等、文件数据所在的数据块位置等。每个文件或目录都对应一个 inode通过 inode 可以快速定位和管理文件。 一般情况下一个文件一个inode基本上每一个文件都有在整一个分区中具有唯一性在Linux内核中识别文件和文件名无关只和inode有关 数据表(Data Block) 存放文件内容 比如文件内容占用了357那么就把357存入int blocks[ 15 ]这个时候有人就会问了如果文件太大怎么办这里就 4*15 kb完全不够用啊 下标0 - 12是直接映射下标13是间接映射下标14是三级映射 inode位图(inode Bitmap) inode位图当中记录着每个inode是否空闲可用。 块位图(Block Bitmap) 块位图当中记录着Data Block中哪个数据块已经被占用哪个数据块没有被占用。 块组描述符表(Group Descriptor Table) 块组描述符表描述该分区当中块组的属性信息 超级块(Super Block) 注意 其他块组当中可能会存在冗余的Super Block当某一Super Block被破坏后可以通过其他Super Block进行恢复。磁盘分区并格式化后每个分区的inode个数就确定了。 如何理解创建一个空文件 分配 inode为新文件分配一个唯一的 inode用于记录文件的相关属性。初始化 inode 信息在 inode 中设置一些基本信息如文件类型通常是普通文件、权限等。关联数据块可能会为文件分配一些初始的数据块但这些数据块目前是空的。在目录中建立链接将文件的名称与对应的 inode 关联起来使其能在文件系统中被找到。 如何理解对文件写入信息  定位通过文件的 inode 找到相应的数据块位置。写入数据将新的信息写入到指定的数据块中。更新 inode修改 inode 中的相关信息如文件大小、修改时间等。可能的磁盘操作实际的写入可能涉及磁盘的读写操作以确保数据的持久保存。 如何理解删除一个文件 将该文件对应的inode在inode位图当中置为无效。将该文件申请过的数据块在块位图当中置为无效。 因为此操作并不会真正将文件对应的信息删除而只是将其inode号和数据块号置为了无效所以当我们删除文件后短时间内是可以恢复的。 立即停止使用存储设备避免新的数据覆盖可能被恢复的文件区域。使用数据恢复软件有一些专门的数据恢复软件可以扫描存储设备尝试找回被删除的文件。 为什么说是短时间内呢因为该文件对应的inode号和数据块号已经被置为了无效因此后续创建其他文件或是对其他文件进行写入操作申请inode号和数据块号时可能会将该置为无效了的inode号和数据块号分配出去此时删除文件的数据就会被覆盖也就无法恢复文件了。 为什么拷贝文件的时候很慢而删除文件的时候很快 拷贝过程拷贝文件需要将数据从源位置读取出来然后写入到目标位置涉及大量的数据传输和处理时间相对较长。删除操作删除文件主要是进行一些标记和资源释放的操作相对较为简单快捷。文件系统结构文件系统在删除文件时可以较快地完成一些内部的调整和清理而拷贝文件需要实际的数据移动和复制。 因为拷贝文件需要先创建文件然后再对该文件进行写入操作该过程需要先申请inode号并填入文件的属性信息之后还需要再申请数据块号最后才能进行文件内容的数据拷贝而删除文件只需将对应文件的inode号和数据块号置为无效即可无需真正的删除文件因此拷贝文件是很慢的而删除文件是很快的。 这就像建楼一样我们需要很长时间才能建好一栋楼而我们若是想拆除一栋楼只需在这栋楼上写上一个“拆”字即可。 如何理解目录 文件组织方式目录是一种用于组织文件的结构它就像文件的“收纳盒”将相关的文件集合在一起。链接和索引目录中包含了文件的名称以及与这些文件对应的 inode 的链接或索引通过这些信息可以找到文件。层次结构目录可以形成层次结构构成文件系统的整体架构方便对文件进行分类和管理。访问入口用户可以通过目录来浏览和操作文件它是文件系统中重要的导航和操作界面。 目录也有自己的内容目录的数据块当中存储的就是该目录下的文件名以及对应文件的inode指针。 注意 每个文件的文件名并没有存储在自己的inode结构当中而是存储在该文件所处目录文件的文件内容当中。因为计算机并不关注文件的文件名计算机只关注文件的inode号而文件名和文件的inode指针存储在其目录文件的文件内容当中后目录通过文件名和文件的inode指针即可将文件名和文件内容及其属性连接起来。 软硬链接 软链接 ln -s 源文件 目标链接 其中-s 选项表示创建软链接源文件是要链接的文件目标链接是创建的软链接的名称和位置。 通过ls -i -l命令我们可以看到软链接文件的inode号与源文件的inode号是不同的并且软链接文件的大小比源文件的大小要小得多。 软链接又叫做符号链接软链接文件相对于源文件来说是一个独立的文件该文件有自己的inode号但是该文件只包含了源文件的路径名所以软链接文件的大小要比源文件小得多。软链接就类似于Windows操作系统当中的快捷方式。 但是软链接文件只是其源文件的一个标记当删除了源文件后链接文件不能独立存在虽然仍保留文件名但却不能执行或是查看软链接的内容了。 硬链接 ln 源文件 目标文件 其中源文件是已有文件目标文件是要创建的硬链接的名称。 通过ls -i -l命令我们可以看到硬链接文件的inode号与源文件的inode号是相同的并且硬链接文件的大小与源文件的大小也是相同的特别注意的是当创建了一个硬链接文件后该硬链接文件和源文件的硬链接数都变成了2。 硬链接文件就是源文件的一个别名一个文件有几个文件名该文件的硬链接数就是几这里inode号为924344的文件有myproc和myproc-h两个文件名因此该文件的硬链接数为2。 与软连接不同的是当硬链接的源文件被删除后硬链接文件仍能正常执行只是文件的链接数减少了一个因为此时该文件的文件名少了一个。 总之硬链接就是让多个不在或者同在一个目录下的文件名同时能够修改同一个文件其中一个修改后所有与其有硬链接的文件都一起修改了。就相当于别名 为什么刚刚创建的目录的硬链接数是2 我们创建一个普通文件该普通文件的硬链接数是1因为此时该文件只有一个文件名。那为什么我们创建一个目录后该目录的硬链接数是2 因为每个目录创建后该目录下默认会有两个隐含文件.和..它们分别代表当前目录和上级目录因此这里创建的目录有两个名字一个是dir另一个就是该目录下的.所以刚创建的目录硬链接数是2。通过命令我们也可以看到dir和该目录下的.的inode号是一样的也就可以说明它们代表的实际上是同一个文件。 注意 一个目录下相邻的子目录数等于该目录的硬链接数减2。 软硬链接的区别 软链接是一个独立的文件有独立的inode而硬链接没有独立的inode。软链接相当于快捷方式硬链接本质没有创建文件只是建立了一个文件名和已有的inode的映射关系并写入当前目录。 文件的三个时间ACM时间 在Linux当中我们可以使用命令stat 文件名来查看对应文件的信息。 这其中包含了文件的三个时间信息 Access 文件最后被访问的时间。Modify 文件内容最后的修改时间。Change 文件属性最后的修改时间。 当我们修改文件内容时文件的大小一般也会随之改变所以一般情况下Modify的改变会带动Change一起改变但修改文件属性一般不会影响到文件内容所以一般情况下Change的改变不会带动Modify的改变。 我们若是想将文件的这三个时间都更新到最新状态可以使用命令touch 文件名来进行时间更新。 注意 当某一文件存在时使用touch命令此时touch命令的作用变为更新文件信息。 三、动态库和静态库 1.动态库和静态库的概念 静态库.a程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。动态库.so程序在运行的时候才去链接动态库的代码多个程序共享使用库的代码。 一般默认生成的可执行程序都是动态的动态库体积小运行时加载只有一份。 2.如何生成静态库 我们生成库其实并不要提供源文件我们其实只需要提供( .o 和 .h)文件用户要使用库的时候直接和用户的文件一链接即可。 你有什么证据呢凭什么说我们其实只需要提供( .o 和 .h)文件呢 下面我们来写一个小代码 // Add.h #include stdio.h extern add(int x, int y);// Sub.h #include stdio.h extern sub(int x, int y);// Mul.h #include stdio.h extern mul(int x, int y); // Add.c #include Add.h int add(int x, int y) {return xy; }// Sub.c #include Sub.h int sub(int x, int y) {return x-y; }// Mul.c #include MUl.h int mul(int x, int y) {return x*y; } 我们使用 gcc -c  生成 .o 文件然后将 .c 文件删除 1、我们先将目标文件 TestMain.c 编译成 TestMain.o。 2、再将 TestMain.o 与其他 .o 文件链接起来。 3、我们发现确实生成了可执行程序 a.out。 4、说明我们其实只需要提供( .o 和 .h)文件没有问题。 这个大概就是库的大概意思我们还需要打包。 我们创建一个makefile make一下生成了一个静态库。 但是这个样子就行了嘛不行。 我们还有一大堆的 .h 文件这样无法很好的给用户使用我们还要把 .h 文件打包起来。 我们再makefile 文件里面加入一个output创建一个mymath_lib的文件夹 这样生成了一个文件夹mymath_lib我们把文件夹压缩一下放在网上就可以给其他用户使用了。 假如我们咋网上下载了一个这样的库我们如何去使用呢 我们需要安装开发环境其实就是将头文件 和 .a 文件拷贝到操作系统的指定目录下面  操作系统的指定的头文件一般在 /usr/include 下面 操作系统的指定的 .a 文件一般在 /usr/lib64 下面 拷贝完成后我们就可以使用了。 我们也可以不安装开发环境直接使用看下面。 3.如何去使用一个静态库  我们将我们生成的静态库放入用户的目标文件夹然后编译发现链接错误 这个时候我们可以知道我们自己写的静态库libmymath.a属于第三方库编译器gcc)不认识。 这个时候我们需要去链接。我们需要使用 gcc -lxxx (xxx代指静态库的库名) -L. 我们发现报错因为 libmymath.a 并不是我们的库名真正的库名是去掉前面的 lib 以及后面的 .a mymath 才是我们的库名。 我们使用正确的库名再次编译。成功生成可执行程序 a.out 。 我们查询 a.out 所依赖链接的库。发现并没有我们自己写的库libmymath.a啊 1、ldd 查询的是动态库的 2、我们自己写的是静态库直接链接到可执行程序里面去了。 3、编译器gcc默认是链接动态库的动态链接但是如果你只提供了静态库.a,那么编译器gcc也没有办法只有单独把用户所指定的静态库.a进行静态链接其他正常动态链接。  4、如果加上 -static ,那么全部就必须是静态链接。 4.如何生成一个动态库 我们创建以个makefile文件生成动态库主要分为两步 先生成目标文件用目标文件生成动态库 我们make验证一下发现确实没有问题生成了动态库libmymath.so。 但是这个样子就行了嘛不行。 我们还有一大堆的 .h 文件这样无法很好的给用户使用我们还要把 .h 文件打包起来。 我们再makefile 文件里面加入一个output创建一个mymath_lib的文件夹 这样就生成了一个动态库 5.如何去使用一个动态库  我们还是用刚才使用过的TestMain.c来演示动态库的使用。 #include Add.h #include Sub.h #include Mul.hint main() {int a 10;int b 20;printf(a b %d\n, add(a,b));printf(a - b %d\n, sub(a,b));printf(a * b %d\n, mul(a,b));return 0; } 说明一下使用该动态库的方法与刚才我们使用静态库的方法一样我们既可以使用 -I-L-l 这三个选项来生成可执行程序也可以先将头文件和库文件拷贝到系统目录下然后仅使用 -l 选项指明需要链接的库名字来生成可执行程序下面我们仅以第一种方法为例进行演示。 此时使用gcc编译TestMain.c生成可执行程序时需要用 -I 选项指定头文件搜索路径用 -L 选项指定库文件搜索路径最后用 -l 选项指明需要链接库文件路径下的哪一个库。 gcc TestMain.c -I./mymath_lib/include -L./mymath_lib/lib -lmymath 与静态库的使用不同的是此时我们生成的可执行程序并不能直接运行。 需要注意的是我们使用-I-L-l这三个选项都是在编译期间告诉编译器我们使用的头文件和库文件在哪里以及是谁但是当生成的可执行程序生成后就与编译器没有关系了此后该可执行程序运行起来后操作系统找不到该可执行程序所依赖的动态库我们可以使用ldd命令进行查看。 可以看到此时可执行程序所依赖的动态库是没有被找到的。 那我们如何区做呢 方法一拷贝.so文件到系统共享库路径下 既然系统找不到我们的库文件那么我们直接将库文件拷贝到系统共享的库路径下这样一来系统就能够找到对应的库文件了。  sudo cp mymath_lib/lib/libmymath.so /lib64 可执行程序也就能够顺利运行了。  方法二更改LD_LIBRARY_PATH  LD_LIBRARY_PATH是程序运行动态查找库时所要搜索的路径我们只需将动态库所在的目录路径添加到LD_LIBRARY_PATH环境变量当中即可。 export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/home/wh/linux_learn/test_24_2_29/work/mymath_lib/lib 可执行程序也就能够顺利运行了。
http://www.dnsts.com.cn/news/25162.html

相关文章:

  • php做电影网站推广引流渠道有哪些
  • 国内做网站大公司有哪些wordpress商城 淘宝客
  • 吴江规划建设局网站创建全国文明城市的宗旨是什么
  • 高中教做网站的软件微网站建设哪家好
  • 定制化网站开发的好处从化定制型网站建设
  • 做网站的宽度为多少钱服务器在哪里
  • 网站建设企业开发建设工程规划许可证查询网站
  • 进网站备案wordpress主题付费
  • 廊坊网站建设的公司成都网站建设 公司
  • 聊城网站开发个人福建住建设厅官方网站
  • 表白网站怎么做wordpress只显示文章标题摘要
  • 网站建设质量管理定义wordpress保存文件
  • 锤子 网站 模版网站开发工程师需要哪些技术
  • 深圳网站建设公司信息商河做网站多少钱
  • 织梦网站被黑wordpress猜你喜欢功能
  • 网站建设及推广好做吗公司内部网站模板
  • 乐山做网站东莞营销网站建设直播
  • 大连市城市建设投资集团网站推广链接怎么制作
  • 做网站都需要什么资料百度搜索首页
  • 免费ppt模板 网站开发网页加速器免费永久
  • 北京海淀网站制作公司襄阳seo优化排名
  • 经典网站设计欣赏淘宝刷单网站建设
  • 一个网站如何优化凡客设计
  • 响应式网站和自适应网站区别环境设计排版哪个网站好
  • 励志网站源码网站建设一条龙
  • 网站建设管理总结华为手机一键优化
  • 网站建设与制wordpress不使用缩略图
  • 建瓯市建设银行网站怎么用dw做地图网站
  • 网站建设导航栏设计wordpress 视频 广告
  • 在国际网站上做贸易怎么发货工业风 网站建设