[POSIX]文件系统(概述)
1.文件名由除系统目录分隔符(unix是/,windows是\)和空字符“\0”外的任意ASCII字符组成,现代系统很多还可以包含UNICODE字符,但是还是推荐使用传统的ASCII码命名.
2.目录不能创建硬链接.
3.文件描述符是一个非负数.
4.文件描述符(fd)是一个非负数,每个进程的fd之间不存在联系,每个进程调用打开文件系统调用时,进程只会按照“从0开始(每个进程从各自的0开始),返回最小的未用的fd”的这个规则返回fd(通常0到2会被系统标准输出输入占用),不同进程打开同一个文件,会有不同的fd返回.
5.一般shell程序会把0、1、2三个文件描述符标准化为shell程序的输入输出和错误输出,换句话说文件描述符0到2已经被这3个标准输入输出占用了.
POSIX也定义了三个常量代表了这三个数字包含在unistd.h头文件上
STDIN_FILENO | 0 |
STDOUT_FILENO | 1 |
STDERR_FILENO | 2 |
代码示例:
#include <fcntl.h>
#include <unistd.h> int main(void){
char s_1[] = "my error.\n";
write(STDERR_FILENO, s_1, );
return ;
}
此代码片段会在控制台,输出"my error.\n".
6.在shell中启动的进程写入STDOUT_FILENO和STDERR_FILENO会输出到屏幕,但是STDOUT_FILENO是带缓冲的IO,而STDERR_FILENO是即刻响应的.
7.由open和openat返回的文件描述符,一定是最小未用的文件描述符,利用这一特性,应用程序可以关闭掉标准的输入输出从而启动自行的输入输出.
代码示例:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h> int main(void){
#define LEN 3
char p_1[] = "./abc.txt";
close(STDOUT_FILENO);
int fd_1 = open(p_1, O_RDWR|O_APPEND|O_CREAT); printf("%d\n", fd_1); return ;
}
以上代码关闭了标准输出,再把它重定向到了进程当前工作目录下的"./abc.txt"文件,这时进程的所有输出,都会被记录到"./abc.txt"上.
8.具有缓冲的I/O,当输入或输出还不至于填满缓冲区时,实际只是I/O到缓冲区,只有在两种情况带缓冲的函数才会输出到设备:
---缓冲区被填满,缓冲区内容自动被刷出.
---程序正确退出(exit(0)),就算缓冲区不被填满也会被刷出.
9.在shell终端,当键入回车键时终端进程实际上会执行两个动作.
---输入当前系统回车字符,至于输入什么字符通常是终端运行系统环境决定的,Unix体系为\n,Windows体系为\r\n.
---发送输入内容,也就是把输入内容写进STDIN.
10.一些带缓冲的,操作字符串的I/O函数,会在读取的返回内容长度n的位置自动填充\0,所以它读取的字符长度实际上只有n-1,例如fgets.
11.一些带缓冲的,操作字符串的I/O函数,在每次调用的时候会自动刷出缓冲区,就像调用fflush(fd)一样,例如fgets.
13.事实上,就算是不带缓冲的I/O函数,如read,write,也不会直接操作存储设备,传统unix系统实现在内核中设有缓冲区高速缓存或页高速缓存,大多数磁盘I/O都是通过缓冲区进行.举个例子,当进程A向文件A写入一个字符,内核并不会马上启动硬件把这一个字节写入存储设备,而是先填充在高速缓冲区,当进程B恰好向文件A读取此字符,内核会在缓冲区返回这个字符,同时会刷新缓冲区,这些操作,对于应用程序本身是感知不到的,除非你把存储设备同时绑定两个系统,如虚拟机和宿主共同访问一个存储设备,你会发现这个细节。
14.Unix还提供了一些函数来操作I/O高速缓存,通常还有一个守护进程定时将缓冲区的内容刷出缓冲区,详情请参考《Unix高级环境编程》3.13 函数sync、fsync和fdatasync.
15.当open/openat以O_APPEND标志打开文件时,调用lseek将不能改变write的偏移位,此时write的偏移位始终会在结尾开始,但是可以改变read的偏移位.
16.当文件不支持lseek时,可以调用lseek(STDIN_FILENO, 0, SEEK_CUR) == -1来判断,切忌一定要看是否等于-1,判断小于0没用,因为有些系统lseek支持设置为负值.
17.lseek仅将当前的文件偏移量记录在内核中,它并不引起任何I/O操作,因此在打开一个空文件,并设置偏移位,并不会为该文件写入任何东西,直到真正调用写入操作为止.
18.O_APPEND具有一定的特殊性,调用操作偏移位函数对write无效的根本原因是,每次write都会从v(i)-node获取文件长度作为自己的偏移量的特性,这就意味着你不能用无O_APPEND标志的fd设置一个跟文件长度对等的偏移位去模拟O_APPEND的行为.
19.当存在多个进程打开同一个文件,那么每个进程的这个fd会各自维护一个注1|文件描述符标志表,这个表包括文件状态标志(读,写,添,同步,非阻塞等信息)和当前文件偏移位,还有指向v(i)-node的指针。所以每个进程对于这个文件的操作偏移位不是共享的,这将会涉及到数据同步的问题,详情参考《Unix高级环境编程》3.10 文件共享 章节.
20.有些例外的情况,不同的进程或同进程不同的fd会引用同一个文件表,例如用来复制fd的dup函数和fork子进程时会发生这样的情况.
21.除root用户外,其余用户只能编辑属于自己名下的文件权限位,详情参考《Unix高级环境编程》4.9 章节.
22.只有root用户可以更新文件的所有者UID,而关于组GID,只有文件所有者可以修改组GID,详情参考《Unix高级环境编程》4.11 章节.
23.目录拥有者可以删除该目录下不属于自己或者不具备权限的文件.
24.一些文件系统不允许用户对目录创建硬链接(就算允许,也仅限于超级管理员),这是因为需要避免循环访问的原因,详情参考《Unix高级环境编程》4.15 章节.
25.一个文件只有一个iNode.
26.目录文件的block保存的是该目录下的目录项,目录项包含一个文件名和一个指向该文件iNode的指针.
27.重命名(或者改变文件路径),实际上是删除原有的目录项,新建一个指向该iNode的目录项.
28.硬链接会在block中创建目录项,目录项指向和这个文件的其他硬链接(如果有)同一个iNode上,关于这个iNode,每增加一个硬链接,就会在它的引用次数(stat.st_nlink)上加1,当删除该文件时,其实只是删除引用这个iNode的目录项,并且会在这个iNode的引用次数上减1,直到引用次数为0时,系统调用才会真正删除这个iNode,并回收它指向的block.
29.软连接则是一个单独的文件,拥有单独的iNode,这个文件的iNode表项中S_IFLNK表明这个文件是一个符号链接,iNode指向block,而block中包含了需要指向的文件的完整文件名(参考《Unix高级环境编程》4.14 章节),删除它并不影响它指向的文件.
30.硬链接要求文件在同一个文件系统,而软连接可以跨文件系统。只有超级用户才有权限为目录增加硬链接.
31.mkdir创建新文件目录时,会自动创建.和..这两个目录项,它们分别指向自己和自己的上一级,详情参考《Unix高级环境编程》4.21 章节.
注1|文件描述符标志表
标志常量 | 说明 |
FD_CLOEXEC | 0(系统默认,exec时不关闭)或1(在exec时关闭) |
*如表格所示,Unix系统目前只定义了一种文件描述符标志
[POSIX]文件系统(概述)的更多相关文章
- POSIX多线程—概述
作者:阿波链接:http://blog.csdn.net/livelylittlefish/article/details/7918110 (整半年没有更新,发几篇以前的读书笔记.) Content ...
- posix thread概述(示例代码)
一个简单的alarm实例 errors.h头文件 #ifndef __ERRORS_H #define __ERORRS_H #include<stdio.h> #include<u ...
- posix thread概述
1. 基本概念 一个Unix进程可以理解为一个线程加上地址空间.文件描述符和其他数据.异步表明事情相互独立发生, 除非有强加的依赖性. 并发指实际可能是穿行发生的事情好像同时发生一样.并行指并发序列同 ...
- nodeJS之fs文件系统
前面的话 fs文件系统用于对系统文件及目录进行读写操作,本文将详细介绍js文件系统 概述 文件 I/O 是由简单封装的标准 POSIX 函数提供的. 通过 require('fs') 使用该模块. 所 ...
- 005.Ceph文件系统基础使用
一 Ceph文件系统 1.1 概述 CephFS也称ceph文件系统,是一个POSIX兼容的分布式文件系统. 实现ceph文件系统的要求: 需要一个已经正常运行的ceph集群: 至少包含一个ceph元 ...
- Ceph 概述和理论
1.1 Ceph概述 官网地址:https://docs.ceph.com/docs/master/ 1.Ceph简介 概述:Ceph是可靠的.可扩展的.统一的.分布式的存储系统.同时提供对象存储RA ...
- Node.js 文件系统
Node.js 文件系统封装在 fs 模块是中,它提供了文件的读取.写入.更名.删除.遍历目录.链接等POSIX 文件系统操作. 与其他模块不同的是,fs 模块中所有的操作都提供了异步的和 同步的两个 ...
- [转载] 文件系统vs对象存储——选型和趋势
原文: http://www.testlab.com.cn/Index/article/id/1082.html#rd?sukey=fc78a68049a14bb2699b479d5e730f6f45 ...
- posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序
posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属 ...
随机推荐
- instanceof 操作符实现原理解析
本文会介绍ES6规范中 instanceof 操作符的实现,以及自定义 instanceof 操作符行为的几个方法. 文中涉及的规范相关的代码皆为伪代码,为了便于理解,其中可能会省略一些参数判断逻辑或 ...
- Groovy 设计模式 -- 抽象工厂 模式
抽象工厂 https://blog.csdn.net/wyxhd2008/article/details/5597975 首先来看看这两者的定义区别: 工厂模式:定义一个用于创建对象的借口,让子类决定 ...
- 理解PHP中的会话控制
会话控制是一种跟踪用户的通信方式,使用会话控制主要基于以下几点:由于http协议的无状态性,使得不能通过协议来建立两次请求之间的关联:对于通常的页面之间的数据传递方式get和post而言,主要处理参数 ...
- SqlServer 左右内连接
- 一颗树下的input框超出的部分打点鼠标移动显示
- 总结PHP如何获取当前主机、域名、网址、路径、端口和参数等
//获取域名或主机地址 echo $_SERVER['HTTP_HOST']."<br />"; //获取网页地址 echo $_SERVER['PHP_SELF']. ...
- Maven 那点事儿(转)
0. 前言 Jason Van Zyl,在 Java 十大风云人物排行榜上或许会看到他. 这兄弟是干嘛的? 他就是 Maven 的创始人,人们都尊称他为“Maven 他爸”. 毋庸置疑,Jason 也 ...
- webpack设置热更新
首先需要在package.json中配置一个脚本参数 --hot "dev": "webpack-dev-server --mode development --hot& ...
- python 中的"*"与"**"
1.Python中 *和**很常见的运算符的用途及其多种使用方式. 本文所述的*和**,指的是*和**前缀运算符,而不是中缀运算符. 所以指的不是乘法和乘幂: 使用*和**将参数传递给函数 使用*和* ...
- Menu显示三个点,不显示内容
先说下menu的使用 首先自定义一个menu选项 <menu xmlns:android="http://schemas.android.com/apk/res/android&quo ...