Linux 文件系统 -- 简述几种文件类型

  Linux 中一切皆为文件,文件类型也有多种,使用 ls -l 命令可以查看文件的属性,所显示结果的第一列的第一个字符用来表明该文件的文件类型,如下:

1、普通文件

  使用 ls -l 命令后,第一列第一个字符为 "-" 的文件为普通文件,如上图所示,普通文件一般为灰色字体,绿色字体的是可执行文件,红色字体的是压缩文件。

文件的权限:

  以普通文件为例,使用 ls -l 命令,可以看到结果的第一列是 -rwxrwxrwx 的形式,其中第一个字符 "-" 表示这个文件为普通文件,它也可以是其他的字符,不同的字符代表不同类型的文件。其后的一串字符表明了该文件的权限,其中:

1)r 表明该文件具有可读权限,若该位置为 "-" ,则表明文件不可读;

2)w 表明该文件具有写权限,若该位置为 "-" ,则表明文件不可写;

3)x 表明该文件具有可执行权限,若该位置为 "-" ,则表明文件不具有可执行权限;

4)第一个 rwx 表示该文件的所有者对该文件的权限;第二个 rwx 表示该文件所属组对该文件的权限;第三个 rwx 表示其他用户对该文件的权限。

创建一个普通文件:

  可以使用 touch 命令来创建一个文件:

touch newfile

删除一个普通文件:

  可以使用 rm 命令来删除一个文件:

rm newfile

 

2、目录文件

  Linux 中的目录也是文件,目录文件中保存着该目录下其他文件的 inode 号 和文件名等信息,目录文件中的每个数据项都是指向某个文件 inode 号的链接,删除文件名就等于删除与之对应的链接。目录文件的字体颜色是蓝色,使用 ls -l 命令查看,第一个字符为"d"(directory)。

目录文件的权限

1)r 表明该目录文件具有可读权限,即可以使用 ls 命令查看该目录的存储情况;

2)w 表明该目录文件具有写权限,即可以往该目录下添加、修改、删除文件;

3)x 表明该目录文件具有可执行文件,即可以使用 cd 命令进入到该目录下。

  可以使用 chmod 指令来改变文件的权限。

创建一个目录:

  可以使用 mkdir 命令来创建一个目录文件:

mkdir directory

删除一个目录:

  可以使用 rmdir 命令来删除一个空目录:

rmdir directory

  如果该目录下有其他文件,则可以使用 rm -r 命令来递归删除该目录下的所有文件。需要注意的是,使用该命令将会删除该目录及目录下的所有数据,过程不可逆,需要谨慎使用:

rm -r directory

 

3、链接文件

  链接文件一般指的是一个文件的软连接(或符号链接),使用 ls -l 命令查看,第一个符号为  "l",文件名为浅蓝色,如下:

   这里,test_softlink 就是一个链接文件,从结果上还可以看到它是文件 test.txt 的软链接,删除原文件 test.txt 的话,对应的软链接文件 test_softlink 也会消失。可以使用 ln 命令来创建一个文件的链接文件:

1)软链接

  软链接(又称符号链接),使用 ln -s file file_softlink 命令可以创建一个文件的软链接文件:

ln -s test.txt test_softlink

  软链接相当于给原文件创建了一个快捷方式,如果删除原文件,则对应的软链接文件也会消失。

2)硬链接

  硬链接,相当于给原文件取了个别名,其实两者是同一个文件,删除二者中任何一个,另一个不会消失;对其中任何一个进行更改,另一个的内容也会随之改变,因为这两个本质上是同一个文件,只是名字不同。使用 ls -i 命令查看,可以发现硬链接的两个文件的 inode 号是一样的:

  同样的,使用 ln 命令可以创建一个文件的硬链接:

ln test.txt test_hardlink

 

4、设备文件

  Linux 中的硬件设备如硬盘、鼠标等也都被表示为文件,即为设备文件。设备文件一般存放在 /dev/ 目录下,文件名为黄色,如下:

  设备文件分两种:

1)块设备文件:

  块设备文件支持以块(block)为单位的访问方式。在 EXT4 文件系统中,一个 block 通常为 4KB 的大小,也就是说每次可以存取 4096(或其整数倍) 个字节的数据。应用程序可以随机访问块设备文件的数据,程序可以自行确定数据的位置,硬盘、软盘等都是块设备。使用 ls -l 命令查看,块设备文件的第一个字符是 "b"(block)。

2)字符设备文件:

  字符设备文件以字节流的方式进行访问,由字符设备驱动程序来实现这种特性,这通常要用到 open、close、read、write 等系统调用。字符终端、串口和键盘等就是字符设备。另外,由于字符设备文件是以文件流的方式进行访问的,因此可以顺序读取,但通常不支持随机存取。使用 ls -l 命令查看,字符设备文件的第一个字符是 "c"(char)。

 

5、管道文件(FIFO文件)

  管道文件主要用于进程间通信,使用 ls -l 命令查看,第一个字符为 "p"(pipe)。可以使用 mkfifo 命令来创建一个管道文件:

mkfifo fifo_file

  在 FIFO 中可以很好地解决在无关进程间数据交换的要求,FIFO 的通信方式类似于在进程中使用文件来传输数据,只不过 FIFO 类型的文件同时具有管道的特性,在读取数据时,FIFO 管道中同时清除数据。

 

文件和目录之文件类型

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

UNIX系统的大多数文件是普通文件或目录,但是也有另外一些文件类型。文件类型包括如下几种:

(1)普通文件(regular file)。这是最常见的文件类型,这种文件包含了某种形式的数据。至于这种数据是文本还是二进制数据对于UNIX内核而言并无区别。对普通文件的解释由处理该文件的应用程序进行。

一个值得注意的例外是二进制可执行文件。为了执行程序,内核必须理解其格式。所有二进制可执行文件都遵循一种格式,这种格式使内核能够确定程序文本和数据的加载位置。

(2)目录文件(directory file)。这种文件包含了其他文件的名字以及指向这些文件有关信息的指针。对一个目录文件具有读权限的任一进程都可以读该目录的内容,但只有内核可以直接写目录文件。进程必须使用特定的函数才能更改目录。

(3)块特殊文件(block special file)。这种文件类型提供对设备(例如磁盘)带缓冲的访问,每次访问以固定长度为单位进行。

(4)字符特殊文件(character special file)。这种文件类型提供对设备不带缓冲的访问,每次访问长度可变。系统中的所有设备要么是字符特殊文件,要么是块特殊文件。

(5)FIFO。这种类型文件用于进程间通信,有时也将其称为命名管道(named pipe)。

(6)套接字(socket)。这种文件类型用于进程间的网络通信。套接字也可用于在一台宿主机上进程之间的非网络通信。

(7)符号链接(symbolic link)。这种文件类型指向另一个文件。

文件类型信息包含在stat结构的st_mode成员中。可以用表4-1中的宏确定文件类型。这些宏的参数都是stat结构中的st_mode成员。

表4-1 <sys/stat.h>中的文件类型宏

文件类型
S_ISREG() 普通文件
S_ISDIR() 目录文件
S_ISCHR() 字符特殊文件
S_ISBLK() 块特殊文件
S_ISFIFO() 管道或FIFO
S_ISLNK() 符号链接
S_ISSOCK() 套接字

 

POSIX.1允许实现将进程间通信(IPC)对象(例如,消息队列和信号量等)表示为文件。表4-2的宏用来确定IPC对象的类型。这些宏与表4-1中的不同,它们的参数并非st_mode而是指向stat结构的指针。

表4-2 <sys/stat.h>中的IPC类型宏

对象的类型
S_TYPEISMQ() 消息队列
S_TYPEISSEM() 信号量
S_TYPEISSHM() 共享存储对象

 

注:Linux系统并不将这些对象表示为文件。

程序清单4-1 对每个命令行参数打印文件类型

复制代码
[root@localhost apue]# cat prog4-1.c 
#include "apue.h"

int 
main(int argc, char *argv[])
{
        int     i;
        struct stat buf;
        char    *ptr;

        for(i=0; i<argc; i++)
        {
                printf("%s: ", argv[i]);
                if(lstat(argv[i], &buf) < 0)
                {
                        err_ret("lstat error");
                        continue;
                }
                if(S_ISREG(buf.st_mode))
                        ptr = "regular";
                else if(S_ISDIR(buf.st_mode))
                        ptr = "directory";
                else if(S_ISCHR(buf.st_mode))
                        ptr = "character special";
                else if(S_ISBLK(buf.st_mode))
                        ptr = "block special";
                else if(S_ISFIFO(buf.st_mode))
                        ptr = "fifo";
                else if(S_ISLNK(buf.st_mode))
                        ptr = "symbolic link";
                else if(S_ISSOCK(buf.st_mode))
                        ptr = "socket";
                else
                        ptr = "** unknown mode **";
                printf("%s\n", ptr);
        }
        exit(0);
}
复制代码

编译后运行该程序:

复制代码
[root@localhost apue]# ./prog4-1 /etc/passwd /etc /dev/initctl /dev/log /dev/tty /dev/fd0 /dev/cdrom
./prog4-1: regular
/etc/passwd: regular
/etc: directory
/dev/initctl: fifo
/dev/log: socket
/dev/tty: character special
/dev/fd0: block special
/dev/cdrom: symbolic link
复制代码

我们特地使用了lstat函数而不是stat函数以便检测符号链接。如若使用了stat函数,则不会观察到符号链接。

为了在Linux系统上编译该程序,必须定义_GUN_SOURCE,这样就能包括S_ISSOCK宏的定义。(我使用的是2.6.18内核Linux,编译上述程序时,并没有自己定义_GUN_SOURCE,编译通过且运行成功。)

早期的UNIX系统版本并不提供S_ISxxx宏,于是就需要将st_mode与屏蔽字S_FIMT进行逻辑“与”运算,然后与名为S_IFxxx的常量相比较。大多数系统在文件<sys/stat.h>中定义了此屏蔽字和相关的常量。如若查看此文件,则可找到S_ISDIR宏定义为:

#define S_ISDIR(mode)    (((mode) & S_IFMT) == S_IFDIR)

转自:

https://www.cnblogs.com/tongye/p/10410098.html

https://www.cnblogs.com/nufangrensheng/p/3501533.html

posted @ 2022-03-20 16:58  凉茶微凉  阅读(959)  评论(0)    收藏  举报