【Linux】文件结构

来源:互联网 发布:数据集成日语怎么说 编辑:程序博客网 时间:2024/06/01 09:54

Linux 是通过索引号 inode 来访问文件的。



文件目录里面的每一个“文件”都有 inode 号,通过 inode 表 最终指向具体的文件位置。(可以通过 ls -i查看) ls -li 查看时 会有一个列,表示这个 inode 号的硬链接数目,请看下图的第3列(start from 1 OvO)
这里写图片描述
这个当一个inode号的硬链接数目为0时,则表示它指向的文件可以被回收(一般标记为可覆盖,也就是不完全删除)有兴趣的可以百度一下unlink

创建硬链接和软链接
这里写图片描述

图片中的第一列中的 4500992 4500993 等就是文件的 inode 索引号。
其中 ln 是创建链接命令, 默认为硬链接, -s 选项表示软链接。
注意到 file 与 它的硬链接 file.hard 的 inode 号码一致,而与软链接 file.soft 不一致。也就是说,硬链接本质上与源文件指向同一个文件,而软链接是额外创建的文件。尝试删除源文件file之后,观察其变化:
这里写图片描述
除去file之后,硬链接仍能继续访问源文件,软链接不可。原因是硬链接的 inode 号仍能访问到具体文件的位置,而软链接,观察到它的文件命名后接 -> file。它可能是通过目录项名“file”来访问源文件。尝试新建一个新的file,观察其结果:
这里写图片描述
附上盗图:


结语: linux文件系统是通过目录项(如file file.soft)的 inode 来访问具体文件,硬链接本质上是复制一个新的硬链接,指向同一个 inode。软链接是创建一个新的文件(从系统中获取 inode)其内容指向目录项。由于他指向的是目录项,这也是软链接可跨越不同文件系统的原因。
观察到新建的文件是992 993 994,也就是文件的创建会向系统申请 inode, 据说 当inode用完的时候,即使有剩余空间也无法继续申请。
不知真假,如果要测的话,可能要不停的 open(CREATE) 吧。。。


文件与设备

(1)/dev/console /dev/tty /dev/null

设备 功能 console 控制台 tty 控制终端,echo “abc” > /dev/tty 可以在终端显示出来 null 常用于 创建空文件 cp /dev/null empty_file

期待第5章的详细讲解

2015-05-25
tty 是终端对应的文件, 可以通过文件IO往里面读写,相当于终端输入和输出。 一般当我们不希望程序的输出被重定向时(可用 isatty 判断),通过直接对tty文件的读写,直接在终端输入和输出。


dup操作


dup系统调用提供了一种复制文件描述符的方法,使我们能够通过两个或者更多个不同的描述符来访问同一个文件。 ———— 摘自《Linux程序设计》

dup是复制文件描述符,返回新的描述符。而open则是创建文件描述符。那么可以对同一个文件两次打开(open)吗?如果有,那open跟dup的区别是?

#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>#include <stdio.h>#include <sys/types.h>void jobs(int in1, int in2) {  printf("in1 is %d, in2 is %d", in1, in2);  if (-1 == in1)  {    write (2, "error occur when open in1\n", 100);    exit(0);  }  if (-1 == in2)  {    write (2, "error occur when open in2\n", 100);    exit(0);  }  lseek(in1, 10, SEEK_SET);  char buffer[20];  int nread;  printf("\nin1:\n");  if ((nread = read(in1, buffer, 10)) > 0 )   {    write(1, buffer, 10);  }  printf("\nin2:\n");  if ((nread = read(in2, buffer, 20)) > 0 )   {    write(1, buffer, 20);  }  printf ("\n");}main1:int main(){  int in1, in2;  in1 = open("file.test", O_RDONLY);  in2 = open("file.test", O_RDONLY);  jobs(in1,in2);  close(in1);  close(in2);  exit(0);}main2:int main(){  int in1, in2;  in1 = open("file.test", O_RDONLY);  in2 = dup(in1);  jobs(in1, in2);  close(in1);  close(in2);  exit(0);}其中file.test的内容片段:#include <unistd.h>#include <sys/stat.h>#include <fcntl.h>#include <stdlib.h>

jobs的工作是:
输出in1 in2的值;将in1向前平移10字节(lseek),再从in1读取10字节,in2读取20字节并输出。
其结果如下:

main1:in1 is 3, in2 is 4in1:unistd.h>in2:#include <unistd.h>main2:in1 is 3, in2 is 4in1:unistd.h>in2:#include <sys/stat.h

两次的fildes值相同,而对于俩次open的读取文件,in1 与 in2 无影响(读写指针相互独立),而对于dup出来的读写指针是共用的,也就是,in1读到20的位置时,in2接着读的时候是从20开始再读20;

感兴趣的同学可以试一下write情况下的。(open的读写指针不共用,相互覆盖。而dup的读写指针共用,不存在覆盖现象(当然如果你lseek强行指针后移…))
总结:open与dup的最大区别?是读写指针独立问题。对于dup,in1的读取会影响到in2的下一次读取位置。
P.S. 文中提到可以用文件锁保证同步(后续补上)。。。


附件:

1,便捷编译c文件:

#!/bin/bashif [ "$#" != 1 ]; then    printf 'the num of parm should be 1'    exit 0finame=$(echo "$1" | cut -d '.' -f 1)gcc -c "$1"echo "compile $1"gcc ${name}.o -o temp.outecho "link ${name}.o"echo "execute temp.out"echo./temp.outecho echo "rm ${name}.o & temp.out"rm ${name}.o 2> /dev/nullrm temp.out 2> /dev/null

这是一个脚本(我取名为c2o),可以将它放在PATH 路径中的某个文件夹中(我的话是mkdir /usr/zhengBin 然后再到~/.bashrc中添加 PATH=/usr/zhengBin:$PATH 记得给c2o x权限)。
可以直接在shell中 c2o xxx.c 运行程序

# 2015-5-24更新# 新增remain_bin保留生成的binary文件, run_bin选项控制是否执行bin文件# 本次修改针对于bin文件执行时需要参数的情况#!/bin/bashif [ "$#" = "0" ]; then    printf 'the num of parm should be more than 0'    exit 0firemain_bin="n"run_bin="n"name=""while [ "$#" -gt 0 ];do    case "$1" in         "--remain_bin")            echo remain binary file            remain_bin="y"        ;;        "--run_bin")            echo run the binary file            run_bin="y"        ;;        *)            name="$1"            echo name is $name            echo \$1 is $1        ;;    esac    shiftdonegcc -c $nameecho "compile $name"name=$(echo $name | cut -d . -f 1)gcc ${name}.o -o "$name"echo "link ${name}.o"if [ "$run_bin" = "y" ]; then    echo "execute temp.out"    echo    TIMEFORMAT="" time ./$namefiecho echo "rm ${name}.o"rm ${name}.o 2> /dev/nullif [ "$remain_bin" = "n" ];then    echo "rm $name"    rm $name 2> /dev/nullfi
0 0
原创粉丝点击