万物皆文件

echo $$ 查看当前的用户线程

二级目录

  1. /bin
  2. binBinary的缩写, 这个目录存放着最经常使用的命令。
  3. /boot
  4. 这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。
  5. /dev
  6. devDevice(设备)的缩写, 该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问
  7. 文件的方式是相同的。
  8. /etc
  9. 这个目录用来存放所有的系统管理所需要的配置文件和子目录。
  10. /home
  11. 用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。
  12. /lib
  13. 这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用
  14. 程序都需要用到这些共享库。
  15. /lost+found
  16. 这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。
  17. /media
  18. linux 系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目
  19. 录下。
  20. /mnt
  21. 系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目
  22. 录就可以查看光驱里的内容了。
  23. /opt
  24. 这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认
  25. 是空的。
  26. /proc
  27. 这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
  28. 这个目录的内容不在硬盘上而是在内存里,我们也可以直接修改里面的某些文件,
  29. 比如可以通过下面的命令来屏蔽主机的ping命令,使别人无法ping你的机器:
  30. echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
  31. /root
  32. 该目录为系统管理员,也称作超级权限者的用户主目录。
  33. /sbin
  34. s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。
  35. /selinux
  36. 这个目录是Redhat/CentOS所特有的目录,Selinux是一个安全机制,类似于windows的防火墙,但
  37. 是这套机制比较复杂,这个目录就是存放selinux相关的文件的。
  38. /srv
  39. 该目录存放一些服务启动之后需要提取的数据。
  40. /sys
  41. 这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs
  42. sysfs文件系统集成了下面3种文件系统的信息:针对进程信息的proc文件系统、针对设备的devfs文件
  43. 系统以及针对伪终端的devpts文件系统。该文件系统是内核设备树的一个直观反映。
  44. 当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。
  45. /tmp
  46. 这个目录是用来存放一些临时文件的。
  47. /usr
  48. 这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的
  49. program files目录。
  50. /usr/bin
  51. 系统用户使用的应用程序。
  52. /usr/sbin
  53. 超级用户使用的比较高级的管理程序和系统守护程序。
  54. /usr/src
  55. 内核源代码默认的放置目录。
  56. /var
  57. 这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日
  58. 志文件。
  59. /run
  60. 是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。
  61. 如果你的系统上有 /var/run 目录,应该让它指向 run

打开关闭文件

open 函数:

  1. int open(char *pathname, int flags)
  2. #include <unistd.h>
  3. 参数:
  4. pathname: 欲打开的文件路径名
  5. flags:文件打开方式:
  6. #include <fcntl.h>
  7. O_RDONLY|O_WRONLY|O_RDWR O_CREAT|O_APPEND|O_TRUNC|O_EXCL|O_NONBLOCK ....
  8. 返回值:
  9. 成功: 打开文件所得到对应的 文件描述符(整数)
  10. 失败: -1 设置 errno
  1. int open(char *pathname, int flags mode_t mode)
  2. 123 775
  3. 参数:
  4. pathname: 欲打开的文件路径名
  5. flags:文件打开方式:
  6. O_RDONLY|O_WRONLY|O_RDWR
  7. O_CREAT|O_APPEND|O_TRUNC|O_EXCL|O_NONBLOCK ....
  8. mode: 参数 3 使用的前提, 2 指定了 O_CREAT 取值 8 进制数,用来描述文件的 访问权
  9. 限。 rwx 0664
  10. 创建文件最终权限 = mode & ~umask
  11. 返回值:
  12. 成功: 打开文件所得到对应的 文件描述符(整数)
  13. 失败: -1 设置 errno
  1. close 函数:
  2. int close(int fd);
  3. 错误处理函数:
  4. errno 相关。
  5. printf("xxx error: %d\n", errno);
  6. char *strerror(int errnum)
  7. printf("xxx error: %s\n", strerror(errno));
  8. void perror(const char *s);
  9. perror("open error");

读文件

  1. ssize_t read(int fd, void *buf, size_t count);
  2. 参数:
  3. fd:文件描述符
  4. buf:存数据的缓冲区
  5. count:缓冲区大小
  6. 返回值:
  7. 0:读到文件末尾。
  8. 成功; > 0 读到的字节数。
  9. 失败: -1 设置 errno
  10. -1 并且 errno = EAGIN EWOULDBLOCK, 说明不是 read 失败,而是 read 在以非阻塞方式读一个设备文件(网络文件),并且文件无数据。

文件描述符

为文件读写 文件打开的第一个参数

PCB进程控制块 本质 结构体
image.png
成员 文件描述符表
文件描述符 0/1/2/3/4.。。/1023 标准可用的最小的
image.png
只能得到文件描述符 0~1023 相当于一个1024个指针数组的下标 指向FILE结构体
得到文件描述符 可用通过它找到一打开的文件 。
文件描述符为可用的最小的
0 —-STDIN_FILENO 输入
1—-STOUT_FILENO
2—-STDERR_FILENO

FILE结构体

主要包含文件描述符。文件读写位置 IO缓冲区三部分内容。

  1. struct file
  2. {
  3. ...
  4. 文件的偏移量
  5. 文件的访问权限
  6. 文件的打开标志
  7. 文件内核缓冲区的首地址
  8. struct operations * f_op
  9. }

查看方法

  1. 1./usr/src/linux-headers-3.16.0-30/include/linux/fs.h

阻塞和非阻塞

阻塞、非阻塞: 是设备文件、网络文件的属性。 文件属性
产生阻塞的场景。 读设备文件。读网络文件。(读常规文件无阻塞概念。)
/dev/tty — 终端文件。
open(“/dev/tty”, O_RDWR|O_NONBLOCK)
—- 设置 /dev/tty 非阻塞状态。(默认为阻塞状态)

例如读文件STDIN_FILENO 就是设备文件 堵塞属性的文件dev/tty
等待输入完才能读出文件内容

read读非阻塞文件
errno = EAGIN 或 EWOULDBLOCK 说明不是read失败而是读取的文件是非阻塞的设备文件(网络文件)并且文件无数据。
image.png
image.png

fcnrl修改文件属性

  1. fcntl
  2. int (int fd, int cmd, ...)
  3. int flgs = fcntl(fd, F_GETFL);
  4. flgs |= O_NONBLOCK
  5. fcntl(fd, F_SETFL, flgs);
  6. flgs:
  7. 获取文件状态: F_GETFL
  8. 设置文件状态: F_SETFL

image.png
获取文件stdin属性信息 加上非阻塞属性 再设置属性
第二个参数可以为F_GETFL F_SETFL

lseek 函数:

  1. off_t lseek(int fd, off_t offset, int whence);
  2. 参数:
  3. fd:文件描述符
  4. offset 偏移量
  5. whence:起始偏移位置: SEEK_SET/SEEK_CUR/SEEK_END
  6. 返回值:
  7. 成功:较起始位置偏移量
  8. 失败:-1 errno

应用场景:

  1. 文件的“读”、“写”使用同一偏移位置。 写完光标会变 再读时候也是在最后 需要将光标移动到开头 lseek(fd,0,SEEK_SET);
  2. 使用 lseek 获取文件大小 int len = lseek(fd,0,SEEK_END);
  3. 使用 lseek 拓展文件大小:要想使文件大小真正拓展,必须引起 IO 操作。

单lseek是不能进行拓展的
od-tcx filename 查看文件的16进制表示形式
od-tcd filename 查看文件的10进制表示形式

4 使用 truncate 函数,直接拓展文件。 int ret = truncate(“dict.cp”, 250);

  1. int ret = truncate("filename",250);
  2. 返回0

参数

传入参数:
1. 指针作为函数参数。
2. 同常有 const 关键字修饰。
3. 指针指向有效区域, 在函数内部做读操作。

传出参数:
1. 指针作为函数参数。
2. 在函数调用之前,指针指向的空间可以无意义,但必须有效。
3. 在函数内部,做写操作。
4.函数调用结束后,充当函数返回值。

传入传出参数:
1. 指针作为函数参数。
2. 在函数调用之前,指针指向的空间有实际意义。
3. 在函数内部,先做读操作,后做写操作。
4. 函数调用结束后,充当函数返回值

文件系统

文件存储

首先了解如下文件存储相关概念: inode dentry 数据存储 文件系统

inode

本质是结构体 存储文件的属性信息 如 权限 类型 大小 时间 用户 盘块位置 。。。也叫做文件属性管理结构 大多数inode都存储在磁盘上 ls -l
小量常用 近期使用的inode会在缓存到内存中

dentry

目录项 本质是结构体 重要成员变量有两个 {文件名,inode} 而文件内容data 保存在磁盘块中

stat 函数

获取文件属性(从inode结构体中获取)
stat/lstat 函数:
int stat(const char path, struct stat buf);
参数:
path: 文件路径
buf:(传出参数) 存放文件属性。
返回值:
成功: 0
失败: -1 errno
获取文件大小: buf.st_size
获取文件类型: buf.st_mode
获取文件权限: buf.st_mode
符号穿透:stat 会。lstat 不会。 软链接的符号穿透 ln -s 得到的文件不会显示是链接文件
ln -l 是不会穿透的 可用看到是一个链接文件
link/unlink:
隐式回收
stat 的宏
image.png

目录操作

getcwd函数

获取进程当前工作目录
char getcwd(char buff,size_t size);
成功buff中保存当前进程工作目录 失败返回NULL

chdir函数

改变当前进程的工作目录
int chdir(const char* path);成功:0 失败:-1

文件的文件描述符复制

为了对文件后续的使用 保存其文件描述符
dup 和 dup2:
int dup(int oldfd);
文件描述符复制。
oldfd: 已有文件描述符
返回:新文件描述符。
int dup2(int oldfd, int newfd); 文件描述符复制。重定向