来源 | Java建设者(ID: javajianshe)
Linux 文件系统基本概念
Linux 中的文件是一个任意长度的字节序列,Linux 中的文件可以包含任意信息,比如 ASCII 码、二进制文件和其他类型的文件是不加区分的。
下面我们介绍一下 Linux 系统根目录下面的目录名
/boot,启动包含引导加载程序的相关文件/etc,配置文件,启动脚本等,包含所有程序所需要的配置文件,也包含了启动/停止单个应用程序的启动和关闭 shell 脚本/lib,系统库文件,包含支持位于 /bin 和 /sbin 下的二进制库文件/media,挂载可移动介质/opt,提供一个可选的应用程序安装目录/root,root 用户的主要目录文件夹/tmp, 系统和用户创建的临时文件,系统重启时,这个目录下的文件都会被删除/var,经常变化的文件,诸如日志文件或数据库等
如果 /usr/local/books是工作目录,那么 shell 命令
就表示的是相对路径,而
cp /usr/local/books/books /usr/local/books/books-replica在 Linux 中经常出现一个用户使用另一个用户的文件或者使用文件树结构中的文件。两个用户共享同一个文件,这个文件位于某个用户的目录结构中,另一个用户需要使用这个文件时,必须通过绝对路径才能引用到他。如果绝对路径很长,那么每次输入起来会变的非常麻烦,所以 Linux 提供了一种
链接(link)机制。以上所示,比如有两个工作账户 jianshe 和 cxuan,jianshe 想要使用 cxuan 账户下的 A 目录,那么它可能会输入
/usr/cxuan/A,这是一种未使用链接之后的图。现在,jianshe 可以创建一个链接来使用 cxuan 下面的目录了。‘
Linux 文件系统不区分磁盘的,这是什么意思呢?一般来说,一个磁盘中的文件系统相互之间保持独立,如果一个文件系统目录想要访问另一个磁盘中的文件系统,在 Windows 中你可以像下面这样。
nerror="javascript:errorimg.call(this);">
而在 Linux 中,是支持
挂载的,它允许一个磁盘挂在到另外一个磁盘上,那么上面的关系会变成下面这样nerror="javascript:errorimg.call(this);">
Linux 文件系统的另外一个特性是支持
加锁(locking)。在一些应用中会出现两个或者更多的进程同时使用同一个文件的情况,这样很可能会导致竞争条件(race condition)。一种解决方法是对其进行加不同粒度的锁,就是为了防止某一个进程只修改某一行记录从而导致整个文件都不能使用的情况。Linux 系统提供了两种锁:共享锁和互斥锁。如果文件的一部分已经加上了共享锁,那么再加排他锁是不会成功的;如果文件系统的一部分已经被加了互斥锁,那么在互斥锁解除之前的任何加锁都不会成功。为了成功加锁、请求加锁的部分的所有字节都必须是可用的。
加锁区域是可以重叠的。下面我们演示了三种不同条件的加锁区域。
nerror="javascript:errorimg.call(this);">
如上图所示,进程在 A 和 B 上同时加了共享锁,其中 6 - 8 字节是重叠锁
nerror="javascript:errorimg.call(this);">
如果此时一个进程尝试在第 6 个字节处加锁,此时会设置失败并阻塞,由于该区域被 A B C 同时加锁,那么只有等到 A B C 都释放锁后,进程才能加锁成功。
nerror="javascript:errorimg.call(this);">
许多系统调用都会和文件与文件系统有关。我们首先先看一下对单个文件的系统调用,然后再来看一下对整个目录和文件的系统调用。
这个系统调用的两个参数是文件名和保护模式
这段命令会创建一个名为 aaa 的文件,并根据 mode 设置文件的保护位。这些位决定了哪个用户可能访问文件、如何访问。
如果在已经存在的文件上调用了 creat 系统调用,那么该文件中的内容会被清除,从 0 开始。通过设置合适的参数,
open系统调用也能够创建文件。为了对一个文件进行读写的前提是先需要打开文件,必须使用 creat 或者 open 打开,参数是打开文件的方式,是只读、可读写还是只写。open 系统调用也会返回文件描述符。打开文件后,需要使用
close系统调用进行关闭。close 和 open 返回的 fd 总是未被使用的最小数量。什么是文件描述符?文件描述符就是一个数字,这个数字标示了计算机操作系统中打开的文件。它描述了数据资源,以及访问资源的方式。授予访问权限
向软件提供条目的位置
当一个进程成功访问一个打开的文件时,内核会返回一个文件描述符,这个文件描述符指向全局文件表的 entry 项。这个文件表项包含文件的 inode 信息,字节位移,访问限制等。例如下图所示
nerror="javascript:errorimg.call(this);">
标准输入的文件描述符是 0 ,在终端中,默认为用户的键盘输入
与错误有关的默认数据流是 2,在终端中,默认为用户的屏幕。
在文件系统调用中,开销最大的就是 read 和 write 了。read 和 write 都有三个参数
缓冲区地址:告诉数据需要从哪里读取和写入哪里这就是所有的参数了,这个设计非常简单轻巧。
Lseek系统调用会更改指针位置的值,以便后续对 read 或 write 的调用可以在文件中的任何位置开始,甚至可以超出文件末尾。lseek 避免叫做 seek 的原因就是 seek 已经在之前 16 位的计算机上用于搜素功能了。
lseek 的返回值是更改文件指针后文件中的绝对位置。lseek 是唯一从来不会造成真正磁盘查找的系统调用,它只是更新当前的文件位置,这个文件位置就是内存中的数字。
fstat调用和stat相同,只有一点区别,fstat 可以对打开文件进行操作,而 stat 只能对路径进行操作。sort <in | head –40
最后一个系统调用是
fcntl,它用来锁定和解锁文件,应用共享锁和互斥锁,或者是执行一些文件相关的其他操作。可以使用 mkdir 和 rmdir 创建和删除目录。但是需要注意,只有目录为空时才可以删除。
使用
chdir系统调用可以改变工作目录。点分享
nerror="javascript:errorimg.call(this);">
nerror="javascript:errorimg.call(this);">

