基础I/O

文章目录

  • 基础I/O
    • 0 . 预备
      • 0.1 C语言接口
      • 0.2 系统接口
    • 1 . 文件描述符 (fd)
      • 1.1 fd的分配规则
        • 重定向
    • 2. 一切皆文件
    • 3. 缓冲区
    • 4. 没有被打开的文件 —— 磁盘文件
      • 4.1 磁盘结构
        • 4.1.1 磁盘的物理结构:
        • 4.1.2 磁盘的逻辑结构:
      • 4.2 磁盘的管理
        • 4.2.1 磁盘区间划分管理
        • 4.2.2 inode
    • 5. 软硬链接

0 . 预备

文件是什么?

文件 = 文件内容 + 文件属性。

所以对于文件的学习,就是要学习文件的内容以及属性。

怎么才能访问文件?

文件存放在磁盘上,只有os能够访问,所以如果用户想要自己访问文件,那么os必须提供文件接口。

C语言等语言中的文件操作是系统提供的文件接口吗?

不是,语言接口是对系统提供的文件接口的封装。不同的语言由于语法的不同,文件操作也会不同,所以这并不是系统接口。

学习系统接口的意义

语言接口有多套,系统接口只有一套,学一套会十套。

不同的系统,系统接口相同吗?

显然不同,所以,如果我们自己写代码直接使用系统接口,那么这段代码的可移植性是不好的。C语言具有可移植性是因为C语言源代码将所有平台代码都实现了一遍,你用啥平台,他就放啥代码。

Linux认为一切皆文件。

狭义的文件就只是仅仅指文件,但是Linux认为只要能够写入,能够输出,即具有 I/O属性的设备都叫做文件。

0.1 C语言接口

fopen

fclose

fscanf

fprintf

C语言文件接口分为两部分,第一是打开文件的方式,第二是对文件进行的操作。

打开文件的方式有很多种

打开代码 意义 若指定的文件不存在
r(只读) 打开一个已经存在的文件进行读取 出错
w(只写) 打开一个文件进行写入 新建一个文件
a(追加append) 打开一个已存在文件并在末尾进行添加 出错

目前只列这么多种,还可以进行组合,也可以添加一个“+”增加一个属性。

0.2 系统接口

上面的所有C语言接口都是封装系统调用接口实现的。

我们要学的系统调用接口有四个

open:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XpB3CUMh-1672026572674)(E:\比特\笔记\文件系统.assets\image-20221208164451327.png)]

open函数返回一个int类型的值,叫做 fd, 也就是我们的文件描述符,若fd为-1表示打开失败,否则成功。

fd 的值为 0, 1, 2分别代表标准输入,输出和错误。

C语言上的stdin, stdout和stderror是对 fd做封装的结构体。

open函数有两种函数原型。这两个函数的区别是是否具有mode这个参数,mode代表文件的权限,mode和之前的chmod一样,通过给八进制数来设置权限,比如说mode设为 0666 ,就是rw-rw-rw-,但是同时也要考虑umask的影响,可以通过umask这个系统接口将umask的初始值设为 0.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nhxX8PaC-1672026572676)(E:\比特\笔记\文件系统.assets\image-20221208203552520.png)]

open函数的第二个参数是 flag,代表操作选项,从文档中可以知道open有

O_RDONLY(只读), O_WRONLY(只写), O_RDWR(读+写), O_TRUNC(如果指定文件存在,就清零,不存在,就创建新的空文件)等等选项,这些选项的组合是通过 ‘或 ‘操作实现的,比如想要实现只读 + 创建新文件或清零就这样写

 umask(0); //设置umaskint fd = open("hello.txt", O_RDONLY | O_TRUNC | O_CREAT, 0666);

close

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kMoRdN2J-1672026572676)(E:\比特\笔记\文件系统.assets\image-20221208204505239.png)]

close的用法很简单,直接将fd传进去就好,

read

从文件中读出数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qgmj6pJ0-1672026572677)(E:\比特\笔记\文件系统.assets\image-20221209120459792.png)]

函数参数:

fd : 表示打开文件的文件描述符。

buf:表示将要读入的数据结构

count:表示要读入的个数

返回值:

返回值的类型是 ssize_t,这是一个正整形,表示的是实际读入的字符个数。

write

1 . 文件描述符 (fd)

在上面的fd就是我们要讲的文件描述符,为什么要有文件描述符,文件描述符是什么呢?

一个进程可以打开多个文件,打开的文件多如牛毛,os为了将其管理起来,也要“先描述,再组织”。

实际上os用了指针数组的方式来管理文件存放的指针指向一个个文件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awGMEy09-1672026572677)(E:\比特\笔记\文件系统.assets\image-20221209115652539.png)]

files_struct中存储着一个个指向已经打开的文件,所谓的文件描述符就是这个指针数组的下标。

1.1 fd的分配规则

fd的分配规则是分配最小的,且没有被打开的文件描述符。

比如如果0, 1, 2,如果被stdin,stdout和stderr占用了,那么新打开的文件就会被安排上后面的数字中的最小值。

当然,如果将0,1,2中的任意一个close掉,比如close(0),后面的新加入内存的文件就会被分配0(因为此时0是最小的,且没有被打开)。

  //狸猫换太子1 #include <stdio.h>2 #include <unistd.h>3 #include <sys/stat.h>4 #include <sys/types.h>5 #include <string.h>6 #include <fcntl.h>7 8 int main()9 {10   umask(0);11   close(1);12   int fd = open("login.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);13   if (fd < 0)14   {15     perror("open");16     return 1;17   }18 19   printf("%d\n", fd);20   fflush(stdout); //如果不刷新缓冲区就不能写入我们的文件21   close(fd);                                                                                                          22   return 0;23 }

这段代码把stdout关闭了,fd就被分配到stdout的位置,而printf和fprintf都是向stdout内写入信息,自然就写入到了login.txt中。也就是说file_struct这个指针数组中下标为1的位置存放的指针实际上指向的不是显示器,而是我们自己的文件。而这里也就是我们的输出重定向的原理。

要注意的是必须加上fflush或者注释close(fd),不然写入不到我们的文件中,原因后面讲。

重定向

在os内部,更改fd对应的内容的指向,就可以实现。

上面讲的仅仅是重定向的原理,实际上我们没必要使用重定向的时候每次都要close原来的fd。在Linux中有一系例如系统调用接口:dup,其中最常用的是dup2.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UajKlv4v-1672026572678)(E:\比特\笔记\文件系统.assets\image-20221209162544152.png)]

dup2函数原型如下

int dup2(int oldfd, int newfd);

通过dup2函数将file_struct中的oldfd下标所在的指针更换成newfd下表所在的指针,依次来实现重定向的功能。

代码示例

   #include <stdio.h> #include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <string.h>#include <fcntl.h> int main(int argc, char* argv[]){                                    if (argc != 2)   return 2;                   umask(0);        //重定向接口     int fd = open("login.txt", O_WRONLY | O_CREAT | O_A    PPEND, 0666);dup2(fd, 1);//让1中内容和fd中内容一致printf("fd:%d\n", fd)                              printf("%s\n", argv[1]);return 0;}//代码输出结果://fd:3
//if_the_swap_success?

由上述代码输出结果可以看出,dup2并不会改变oldfd的值,仅仅是改变了newfd的值,所以可以的话,尽量手动关闭oldfd。

2. 一切皆文件

之前一直说Linux下一切皆文件,但是为什么这么说呢?之前一直都只是感性的认识,凭什么这么说呢?

思考一个问题:用C语言如何实现面向对象方法 ?

在C++的类中不仅能包含成员变量,还能够包含成员函数,而在C语言中,可以使用函数指针这样的方式来完成一个面向对象的结构。

struct
{//成员变量int (*read)(int n, void *buf);//函数指针,指向方法int (*write)(int n, void *buf);
};

而我们说一切皆文件,也就是把键盘,显示器,磁盘,网卡等外设全部一视同仁了,但是这些设备他的物理结构就是不一样的呀,所以他们的访问方式必须是不一样的,那为什么还说一切皆文件呢?

答案就在于上面的struct,尽管你们的读写方式是不同的,但是我同样的可以用一个struct来描述你,只不过函数指针指向你特定的函数,所以在上层看来,所有的外设都一样,都可以用这个struct来描述。同时struct的数量多起来后,也是需要“先描述,再组织”的。

所以才说,Linux下 “一切皆文件”。

3. 缓冲区

缓冲区其实本质上就是一段内存空间,缓冲区存在的意义就是提高效率,他属于是拒绝了一个一个数据刷新的策略,是积攒一些数据后再刷新。

因此缓冲区其实很像快递。而缓冲区的刷新策略和快递的发货策略也很相像

  • 立即刷新

  • 行刷新(刷新\n之前的所有数据)

  • 满刷新数据满了之后再刷新

  • 特殊情况:

    1.用户强制刷新:fflush

    2.进程退出

一般而言 行缓冲的的设备文件 – 显示器

全缓冲的设备文件 — 磁盘文件

但是,所有的设备永远都倾向于全缓冲,因为这样可以有效减少IO操作(IO操作太耗费时间)。

一个例子:

  1 #include <stdio.h>2 #include <string.h>3 #include <sys/types.h>4 #include <sys/stat.h>5 #include <fcntl.h>6 #include <unistd.h>7 8 9 int main()10 {11   //C语言提供接口12   printf("%s", "hello printf\n");13   fprintf(stdout, "%s", "hello fprintf\n");14 15   //os提供接口16   const char* s = "hello write\n";17   write(1, s, strlen(s));18 19   fork();                                        20   return 0;21 }

这段代码在运行之后向显示器上打印,那么结果是这样

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KGbJP4Wu-1672026572678)(E:\比特\笔记\文件系统.assets\image-20221209185747629.png)]

如果有fork函数,结果则截然不同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V5G8wCvk-1672026572679)(E:\比特\笔记\文件系统.assets\image-20221209185814010.png)]

可以看到,os提供的接口没有重复打印,但是C语言提供的接口却重复打印了

还记得之前说的那个close为什么要加fflush或者注释close的疑问吗?

之前代码再粘贴一下

  //狸猫换太子1 #include <stdio.h>2 #include <unistd.h>3 #include <sys/stat.h>4 #include <sys/types.h>5 #include <string.h>6 #include <fcntl.h>7 8 int main()9 {10   umask(0);11   close(1);12   int fd = open("login.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);13   if (fd < 0)14   {15     perror("open");16     return 1;17   }18 19   printf("%d\n", fd);20   fflush(stdout); //如果不刷新缓冲区就不能写入我们的文件21   close(fd);                                                                                                          22   return 0;23 }

这个时候调用的是printf函数,向stdout的缓冲区中写入了对应的数据,但是此时stdout对应的是磁盘文件,虽然写入了‘\n’,但是仍然不会刷新,当使用close将文件刷新后,stdout的缓冲区数据就无法刷新了。因此文件中没有内容。

从上述现象中可以知道,缓冲区绝对不是os提供的,而是C标准库提供的,因为如果是os提供的,那么系统接口应该也被重复。

第一种结果是向显示器中打印,显示器采用的是行刷新的策略,所以在fork执行的时候,缓冲区已经完全刷新了,所以此时并不会出现重复。

第二种结果中我们进行了输出重定向,向磁盘文件上写入,而磁盘文件是满刷新,fork执行时,明显缓冲区还不会刷新,所以此时如果父子进程退出,就会进行缓冲区刷新,缓冲区刷新要进行写时拷贝,同时由于缓冲区而由于缓冲区是C语言的规定,所以只有C语言的接口受限制,os的接口并不受控制。

缓冲区在哪?

事实上,在之前提到的每个文件都具有的文件结构体file_struct中,每次fputs,fprintf啥的都是先写入到缓冲区中、根据不同的缓冲刷新策略进行刷新。

stderr —— 2 的辨析

1 和 2对应的都是显示器文件,但是它俩是不同的,如同认为一个显示器文件被打开了两次。做一个代码测试

由代码测试可以知道,我们对1做重定向并不会影响2,所以其实1和2是独立的。

perror:perror函数会根据全局的错误码自动输出对应的错误信息。

errno:全局变量,表示错误码。包含在头文件errno.h中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HtXMSqLP-1672026572679)(E:\比特\笔记\文件系统.assets\image-20221212213217417.png)]

strerr:错误信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HfeWwGjH-1672026572680)(E:\比特\笔记\文件系统.assets\image-20221212213133150.png)]

4. 没有被打开的文件 —— 磁盘文件

学习目标

  1. 如何对磁盘文件进行分门别类的存储,用来支持更好的存取
  2. 了解磁盘

4.1 磁盘结构

4.1.1 磁盘的物理结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZBj4o2Xy-1672026572680)(E:\比特\笔记\文件系统.assets\20200330190841250.png)]

盘面:俯视看磁盘好像只有一个面,但是侧面观看就会发现一个磁盘具有许许多多的磁片。盘面看起来是光滑的,但实际上他是由许许多多个小磁铁组成的(因为磁铁具有二面性,符合计算机的0,1属性),磁头通过改变磁铁的南北极朝向写入数据。

磁头: 上图的 Read / write heads,磁头和盘面之间有一定的距离,属于是悬浮在盘面的上空,通过静电效应改变磁铁朝向。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2ydn0GL-1672026572680)(E:\比特\笔记\文件系统.assets\v2-7ef4dd23b909affc4c5529bad4b0564b_r.jpg)]

磁道:磁道指上图的一个同心圆,每一个同心圆被称为一组磁道,数据就存放在磁道上。(所以并不是整个盘面都能存放数据)

扇区:磁道上的一段弧段被称为扇区,磁盘的读写以扇区为基本单位。扇区的大小为512字节。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JBPYvcum-1672026572681)(E:\比特\笔记\文件系统.assets\20191109164411288.png)]

柱面:柱面就是以一个磁道为底面,所有磁片的厚度为高度的一个柱形。

如何寻找到一个扇区进行写入?

chs方式:

  1. 找到是哪一个面(磁头)
  2. 找到是哪一个磁道(柱面)
  3. 找到是哪一个扇区

通过这样的方式可以找到磁盘上的任意一个扇区进行写入。

4.1.2 磁盘的逻辑结构:

磁带示例:一卷磁带扯长开来就是一个线性结构,一条长带

–> 将磁盘盘片抽象成线性结构 --> 数组。(LBA)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yyv94txT-1672026572681)(E:\比特\笔记\文件系统.assets\image-20221213115120883.png)]

找到扇区的位置 --> 找到数组中对应的位置

对磁盘的管理 --> 对磁盘数组的管理

将磁盘进行划分 --> 对磁盘数组的划分

对磁盘的管理 --> 对磁盘数组小分区的管理

因此只要管理好一个个小分区,整个磁盘就能够管理好。

4.2 磁盘的管理

4.2.1 磁盘区间划分管理

接下来要讲的就是关于小分区的管理,如下图所示,一个大分区被分成一个个小分区,这些小分区又被分成更小的分区,只要管理好这些小分区,其他的分区都采用类似的方法进行管理。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QYP8uqE4-1672026572682)(E:\比特\笔记\文件系统.assets\image-20221213101250127.png)]

上述的一个Block_Group就是一个文件系统。

虽然磁盘以扇区(512字节)为基本单位,但是os和磁盘的IO操作的基本单位是4KB, 这是因为512字节太小,会增加IO操作次数降低效率。而且如果os的基本单位和磁盘一样,那就是强耦合,因为如果基本单位一样的话那么磁盘基本单位一变,os也要跟着变,硬件和软件联系紧密,强耦合。

Boot block :存放启动信息

Super blocks:存放的是整个分区,即上图的**第一个矩形(包括所有的Block group和Boot block)**的文件系统属性信息,比如有多少个块组,每个块组的使用情况,但是为甚么整块的信息要放到一个分区内呢?这是因为要防止丢失数据,磁头容易刮花磁片,如果一个分区的Super Blocks损坏可以用另一个区域的Super Blocks进行拷贝恢复。并不是每一个分组都有,前几个会有。

Data blocks:存放对应文件的内容,基本单位是bolck,一个block大小为4KB(8 * 512字节), 也叫做块。

inode table:存放对应文件的属性,基本单位是inode,由一个个的ionode组成table,一个inode的大小是128字节,存放文件的inode编号,文件属性,存放当前文件的块组的编号等内容。

Block Bitmap : 用来管理Data Blocks,假设Data Blocks中有n个块,那么 Bitmap中就有n个比特位,这些比特位是1就表示该block被占用,是0表示可使用。

inode Bitmap:和Block Bitmap类似,用来管理inode Bitmap,如果有n个inode,那么Bitmap中就有n个比特位,是1表示该inode空间已经被占用,0表示可使用

Group Describer Table:存储inode和block的描述信息,例如: 总共有多少个inode,目前的使用情况;总共有多少个block,目前的使用情况。

一个文件对应着一个inode,一个inode编号。

但是,文件大部分不可能只有4kb,因此,一个文件绝大多数情况下不可能只占用一个block块,那么该如何找到该文件对应的内容呢?

在inode中就存储了这个文件占用的块数组的编号

struct inode
{int _inode;//inode编号//...文件描述信息int _blocks[20]; //存储对应文件占用的Block的编号
};

所以只要找到inode编号就能够访问文件属性以及内容了。

但是还有一个问题,如果文件特别大呢?

其实Data block中也不是所有的data block只能存文件数据,也可以存其他块的编号,要知道一个block有4KB,能存储的指向文件的指针的数量就非常可观了。

4.2.2 inode

如何知道inode呢?

在Linux的inode属性中,是没有文件名这一内容的!!

那么文件名去哪了呢?

答案是在上级目录的data block中!!!

目录的内容,也就是目录的data blocks中存放的是文件名 和 inode 的映射关系,在一个目录下文件名是唯一的,而同时在一个文件系统中inode也是唯一的,所以他们互为Key值。

创建一个文件,文件系统做的事

touch test.txt

首先在inode Bitmap中遍历找到第一个为0的inode位,置为1.对Block Bitmap做同样的事情,如有必要对blocks进行数据写入。根据目录的inode找到目录的Data Blocks,将这个文件inode编号以及文件名写入目录的Data Blocks。

删除一个文件,文件系统所做的事

rm -f test.txt

根据文件名,在上级目录中找到自己的inode,根据inode找到对应的inode bitmap和block bitmap,将该文件对应的位图置为0。然后在目录的data blocks中文件名和inode的映射关系去掉。

查看一个文件,文件系统所做的事

cat test.txt

inode, data blocks所占用的空间是固定的

所以就会导致还有空间但是无法创建文件。

5. 软硬链接

软硬链接通过 ln 命令执行

#软链接
ln -s testLink soft.link
#硬链接
ln testLink1 hard.link

软硬链接的本质区别:

是否具有独立的inode,软链接具有独立的inode,硬链接没有。

所以软链接是一个独立的文件,而硬链接不是。

软链接:

有一个独立的文件,上述指令生成一个链接文件testLink --> soft.Link,这个testLink实际上指向的是soft.Link的路径,执行testLink相当于执行soft.Link,所以软链接相当于一个快捷方式。

硬链接:

没有独立的文件,硬链接就是在指定的目录的Data Blocks中,写入硬链接文件名和指定的文件的inode的映射关系。硬链接文件和原文件共用一个inode。硬链接相当于起别名。

在属性中有这么一个数字,他在删除文件前是2,删除文件后是1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2R2wS2cl-1672026572683)(E:\比特\笔记\文件系统.assets\image-20221215165556277.png)]

​ 删除前

rm -f test

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S4R7FEpO-1672026572683)(E:\比特\笔记\文件系统.assets\image-20221215165813830.png)]

​ 删除后

这个数字叫做硬链接数。

前面讲过的是一个文件只有一个inode,inode是唯一的,这里要完善一下说法:inode对于文件是唯一的,但是一个inode可以对应若干个文件。

在inode的结构中,有一个计数器,用来计算使用这个inode编号的文件数,这个数就是硬链接数。所以其实我们删除一个文件其实是对这个计数器减减,当硬连接数为0时,这个inode空间就被标为可用了。

unlink 系统调用

unlink soft.link
unlink hard.link

unlink 清零对应文件的硬链接数。

默认创建目录,硬链接数默认是2,这是因为在目录中存在两个隐藏文件: . 和 … 。

[外链图片转存中…(img-2R2wS2cl-1672026572683)]

​ 删除前

rm -f test

[外链图片转存中…(img-S4R7FEpO-1672026572683)]

​ 删除后

这个数字叫做硬链接数。

前面讲过的是一个文件只有一个inode,inode是唯一的,这里要完善一下说法:inode对于文件是唯一的,但是一个inode可以对应若干个文件。

在inode的结构中,有一个计数器,用来计算使用这个inode编号的文件数,这个数就是硬链接数。所以其实我们删除一个文件其实是对这个计数器减减,当硬连接数为0时,这个inode空间就被标为可用了。

unlink 系统调用

unlink soft.link
unlink hard.link

unlink 清零对应文件的硬链接数。

默认创建目录,硬链接数默认是2,这是因为在目录中存在两个隐藏文件: . 和 … 。

. 表示当前目录,当然也就是当前目录的别名,所以 . 是当前目录的一个硬链接。

文件系统(内存上的 + 磁盘上的)相关推荐

  1. FAT32 文件系统在磁盘上的结构

    FAT32 文件系统在磁盘上的结构 文章目录 FAT32 文件系统在磁盘上的结构 卷结构 数据区域的安排 物理地址 物理扇区号 逻辑扇区号 分区区域和常规区域 用户区域的安排 簇 簇的状态 分区区域的 ...

  2. 文件系统,你有想过怎么访问磁盘上存储的数据吗

    文件系统示意图: 可以看到,这种数据结构是基于数组和链表的组合,是典型的树形结构. 想要加载某个存在于磁盘上的文件,比如想查找[G:\pic\学习截图\文件系统示意图.png],文件系统查找应用就会以 ...

  3. EXT4 之 文件系统在磁盘上的布局 之一

    前言 术语 综述 块Blocks 布局 可调整的block groupFlexible Block Group 元组块Meta Block Groups block group推迟初始化 特殊的ino ...

  4. 磁盘上重复的贴图在内存中也会重复存在

    磁盘上重复的贴图在内存中也会重复存在 posted on 2019-03-26 22:02 时空观察者9号 阅读(...) 评论(...) 编辑 收藏

  5. linux如何改磁盘文件系统名,如何在Ubuntu上设置文件系统(磁盘)配额

    文件系统配额是Linux内核中的标准内置函数. 配额确定文件支持用户活动必须具有的空间量. 磁盘配额还限制了用户可以在系统上创建的文件数量. 支持配额系统的文件系统包括xfs,ext2,ext4和ex ...

  6. Ubuntu中文件系统根目录上的磁盘空间不足的详细解决方案

    目录:Ubuntu中文件系统根目录上的磁盘空间不足的详细解决方案 一.问题提出 二.解决问题 2.1 安装gparted管理器 2.2 打开 2.3 右键点击分区,选择调整大小/移动 一.问题提出 在 ...

  7. Python上传磁盘和网络图片,内存图片,使用requests

    参考:http://www.jianshu.com/p/c80865b2057e 从磁盘上传: open(path, 'rb') #打开文件 os.path.basename(path) #获取文件名 ...

  8. Linux内存技术分析(上)

    Linux内存技术分析(上) 一.Linux存储器 限于存储介质的存取速率和成本,现代计算机的存储结构呈现为金字塔型.越往塔顶,存取效率越高.但成本也越高,所以容量也就越小.得益于程序访问的局部性原理 ...

  9. mysql的索引文件_MySQL:索引在磁盘上的存储

    一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上.这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个 ...

最新文章

  1. 【机器学习实战】第3章 决策树(Decision Tree)
  2. 我家的漫路超市——怎么开淘宝网店
  3. GAN在Image To Image translation 和Inverse Problem中的应用
  4. java 热补丁_Android热补丁之AndFix原理解析
  5. react学习(43)----react中将一个元素渲染为 DOM
  6. C++:18---const关键字(附常量指针、指针常量、常量指针常量)
  7. ftl转PDF服务器上中文不显示,解决Linux中swftools转换中文pdf时出现乱码问题
  8. java12/6作业1
  9. 加强计算机网络应用,加强计算机网络管理技术的创新应用
  10. 怎么用计算机同步文件夹,DSynchronize同步电脑本地文件夹教程
  11. idea集成SVN后查看当前文件修改的历史版本
  12. 谷歌地球下载及功能介绍
  13. Grafana 简单设置
  14. 微信小程序之扫普通链接二维码打开小程序实现动态传递参数及踩坑总结
  15. 熊出没全集光头强的机器人_熊出没:其实光头强早就不想当伐木工了,这些细节足以说明一切...
  16. 数学建模 之 matlab初学两天搞定基础 极限求导积分篇(5/5)
  17. 程序员常用资源工具集合(建议收藏)
  18. 初中物理60个重要知识点
  19. 简单七个步骤写一份策划方案(上)
  20. 树莓派离线语音唤醒snowboy

热门文章

  1. Numerical Optimization和Convex optimization 两本书的选择?
  2. 图像资源Images Assets
  3. hbase1.xx版本出现元数据不一致情况处理
  4. 基于知识图谱和推荐系统的统一药物靶点相互作用预测框架
  5. 解决 cannot connect to 192.168.1.136:5555: 由于目标计算机积极拒绝,无法连接。 (10061)
  6. DeviceIoControl 错误码:error code 87 问题解决
  7. 计算机毕业设计SSM电力公司员工安全培训系统【附源码数据库】
  8. strlen()函数
  9. SAT阅读常见重要词汇
  10. 神经网络学习小记录52——Pytorch搭建孪生神经网络(Siamese network)比较图片相似性