磁盘扇区、IO块、inode、文件、目录、硬链接与软链接到底是什么

磁盘扇区、IO块、inode、文件、目录、硬链接与软链接到底是什么,第1张

磁盘扇区、IO块、inode、文件、目录、硬链接与软链接到底是什么?

自己理解了一下,记录一下备忘。

1、扇区

扇区是磁盘盘片上的一个物理划分,是真真实实存在看得见摸得着的东西。

我们先来看看如何查看一个磁盘的一些信息,可以使用fdisk -l命令查看。我这里有多块盘,但我只截图了一个在这里展示,如图所示,我截取的这块盘为/dev/sda。

看红框所示,Unit是单元的意思,sector是扇区的意思。即磁盘的存储单元是扇区。

从图中第一行还可以看到这块盘的大小为5996G,总共有1171062784个扇区。

从第二行可以看到每个扇区的大小为512bytes。

从第三行可以看到扇区的逻辑大小为512bytes,物理大小为512bytes。

从上图的帮助文档来看,扇区的逻辑大小可以修改,最小为512bytes,最大为4096bytes。(不同的系统,扇区的大小不一样)

除了扇区,磁盘还有哪些物理部件?

2、IO块(磁盘块)

我们平时常说磁盘块,可能会以为它是磁盘的一个物理分区,其实不是的。

扇区是磁盘存储的最小单元。往大了说,还有磁道、盘片等。

那既然磁盘块不是磁盘的物理分区,那么它是啥呀?

我们或许都有这样一个常识认知,就是磁盘的IO速率是非常慢的,如果在读取数据的时候,先读取了一个扇区的数据,发送给上层应用后,又返回来读下一个扇区,再发送给上层应用,如此循环反复,上层应用需要与磁盘进行多次交互,这就很浪费时间了;

所以就引入了磁盘块这么一个概念,它在逻辑层面将多个连续的扇区当作一个整体,然后在读取数据的时候以逻辑层面上的磁盘块为单位,将磁盘块所包含的扇区的数据都一次性读出来发给上层应用。

所以我们要区分开扇区、磁盘块这些概念所对应的对象是不同的:

扇区对应的是硬件层面,它是磁盘面的区域划分,是一个真真实实存在的物理部件;

而磁盘块对应的是软件层面,它在逻辑层面将多个连续的扇区当作一个整体。

比如磁盘扇区大小一般为512字节,而块大小一般为4096字节,那么每一个块就记录着连续的8个扇区;数据不是存在块里的,而是存储在扇区,而块记录哪些扇区是属于自己的。

如何查看一个IO块的大小:

1)在root用户下,执行tune2fs -l /dev/sda | grep "Block Size"

3、inode

每个文件都有数据以及元数据,数据就是文件内容了,它存储在磁盘的数据区;

而文件元数据包括下图这些项:

文件大小、文件块信息、一个块的大小、文件类型(普通文件、目录还是符号链接)、设备号、索引节点编号、硬链接数、文件的访问时间、文件内容的修改时间、文件属性的修改时间

每个文件都会对应一个inode,而每个inode都有唯一一个编号,如何查看文件的inode编号呢?

1)可以使用stat filename来查看

2)或者切换到文件所在目录后,使用ll -i命令来查看,得到的结果中第一列即为文件的inode编号。

我们刚才说到每个索引节点(inode)都有一个唯一的编号,这个编号在每个磁盘上都是有限的,当inode编号分配完了之后,就不能再创建新文件了;

因为文件都需要对应一个唯一的inode,而每个inode又需要对应唯一的编号,而编号又是有限的,所以当分配完了之后,就没法创建inode了,也就没法创建文件了。

有时候可能会发现这样的现象:就是我们想要创建一个新文件,但是发现创建不了了。

于是我们需要排查问题,怎么排查呢?

首先我们先看下是不是磁盘写满了,使用df -hl查看磁盘的使用率,如果达到了100%,那说明盘写满了,我们需要删除些东西以释放存储空间;

但是如果我们查看了磁盘使用率之后,发现不是磁盘满了,磁盘还有很多空闲的空间,那该怎么办?

可以联想到我们上面说过的,看下inode编号是不是用完了,即看下inode编号的使用率?

可以使用df -i来看下磁盘inode编号的使用率,如果发现是inode编号的使用率达到了100%了,那还是得删除些文件以释放占用的inode编号。

会不会有人有疑问?为什么磁盘空间还有这么多,inode编号就用完了?

这大概率是创建的小文件太多了,你想啊,每个文件都要对应一个inode编号,inode编号是有限的,虽然磁盘空间也有限,但是如果文件系统中是以小文件居多,每个文件就占那么点空间,inode编号的消耗速率大于磁盘空间的消耗速率,这就极有可能出现上述inode编号用完了,但是磁盘空间还剩余很多的情况。

4、文件与目录

在linux系统中,一切皆文件。

在linux中怎么判断是文件还是目录呢?

1)通过ll命令判断:

如果开头是d,那就是目录(d即directory的缩写),如果开头是-,那就是普通文件。

2)通过stat命令判断:

5、硬链接与软链接

当我们创建一个文件时,该文件的文件名其实就是一个硬链接,一个文件至少有一个硬链接,但是一个硬链接不可以指向多个文件。

硬链接有什么作用:文件系统通过硬链接可以找到inode编号,进而找到inode,通过获取inode里存储的文件元数据可以读取到磁盘中存储的文件数据。

怎么查看文件的硬链接数呢?

1)通过ll查看:

第二列即为硬链接数

有没有注意到,普通文件的硬链接数与目录的硬链接数是不一样的,普通文件只有一个硬链接,而目录则有两个,这是为什么?

因为对于目录文件而言,除了可以通过目录名获取到文件的inode之外,还可以通过(点号)获取,因为点号表示当前目录。

所以我们看到目录的硬链接数是2个。

2)还可以通过stat查看文件的硬链接数:

软链接是什么?软链接其实是一个独立的文件(分类为符号链接),它有自己的inode,它的inode里存储的是它所指向的文件的信息;由于软链接与它指向的文件是两个独立的文件,所以删除软链接并不会影响它指向的文件。

通过ln -s 123 softlink123建立一个软链接指向文件123

通过stat softlink123可以看到该文件是一个符号链接,即软链接,它有自己的inode,所以它是一个独立的文件,由于它的inode里存储的是它指向的文件的信息,所以通过软链接softlink123也可以读取到文件123的数据

可以看到通过硬链接和软链接读取到的文件内容是一样的

既然文件名不知道是什么,用directorygetfiles去取得该目录下的文件,就可以得到文件名了

SystemIODirectory

GetFiles(String)

返回指定目录中文件的名称(包括其路径)。

例子:

string

targetDirectory

=

"c:\\windows";

//例如

string

[]

fileEntries

=

DirectoryGetFiles(targetDirectory);

foreach(string

fileName

in

fileEntries)

这里就可以得到该文件名称了

FileInputStream fis = new FileInputStream("aatxt")

FileOutputStream fos = new FileOutputStream("btxt");

int a = fisread();

while(a != -1)

{

foswrite(a);

a = fisread();

}

fisclose()

fosclose()

可以通过字符串截取来实现,找到最后一个"\"的位置然后截取,就可以去掉路径,同理找到""的索引再截取就去掉文件后缀名了。

string str="F:\cs\readmetxt";

string file=strSubstring(strLastIndexOf("\\") + 1);//去掉了路径

string name=fileSubstring(0,fileLastIndexOf(""));//去掉了后缀名

你那个type没看出有啥用,给你改了

import javaioFile;

import javautilVector;

public class A {

public static void recursion(String root, Vector<String> vecFile) {

File file = new File(root);

File[] subFile = filelistFiles();

for (int i = 0; i < subFilelength; i++) {

if (subFile[i]isDirectory()) {

recursion(subFile[i]getAbsolutePath(), vecFile);

} else {

String filename = subFile[i]getName();

vecFileadd(filename);

}

}

}

public static void main(String[] args) {

Vector<String> vecFile = new Vector<String>();

recursion("E:/A", vecFile);

for (String fileName : vecFile) {

Systemoutprintln(fileName);

}

}

}

=================

文件名都给你打出来了,你还想咋处理????

=================

得不到,文件名只不过是一个字符串,没有任何实际意义,除非得到文件名的时候得到文件大小。我给你改了下,Vector里放的是File而不是文件名了,你想干啥都行了

import javaioFile;

import javaioFileInputStream;

import javaioFileNotFoundException;

import javaioIOException;

import javautilVector;

public class A {

public static void recursion(String root, Vector<File> vecFile) {

File file = new File(root);

File[] subFile = filelistFiles();

for (int i = 0; i < subFilelength; i++) {

if (subFile[i]isDirectory()) {

recursion(subFile[i]getAbsolutePath(), vecFile);

} else {

vecFileadd(subFile[i]);

}

}

}

public static void main(String[] args) throws FileNotFoundException, IOException {

Vector<File> vecFile = new Vector<File>();

recursion("E:/A", vecFile);

for (File file : vecFile) {

Systemoutprintln(filegetName() + " " + new FileInputStream(file)available());

}

}

}

package comtexst;

import javaioFile;

import javaioFileInputStream;

import javaioFileNotFoundException;

import javaioIOException;

public class GetFileMessageOfDisk {

/

@param args

/

public static void main(String[] args) {

File file = new File("D:/");

getMessage(file);

}

private static void getMessage(File file){

File[] files = filelistFiles();

if(files==null){

files = new File[0];

}

for(int i=0;i<fileslength;i++){

if(files[i]isDirectory()){

Systemoutprintln(files[i]getPath());

getMessage(files[i]);

}else{

try {

int length = new FileInputStream(files[i])available();

Systemoutprintln(files[i]getName()+" 长度:"+length+" 大小:"+length/1024+"KB");

} catch (FileNotFoundException e) {

eprintStackTrace();

} catch (IOException e) {

eprintStackTrace();

}

}

}

}

}

以上就是关于磁盘扇区、IO块、inode、文件、目录、硬链接与软链接到底是什么全部的内容,包括:磁盘扇区、IO块、inode、文件、目录、硬链接与软链接到底是什么、c# 已知路径如何获取文件名(不知文件名是什么)、java中,怎样用IO流把任意路径的任意文件的字节读取成二进制等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/9615732.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存