国外photoshop教程网站,南昌网站建设机构,国家城乡住房建设部网站,网页代码小游戏1.文件 1.1文件属性 当我们创建文件时#xff0c;文件就有了对应的属性#xff0c;可以用mkdir创建目录#xff0c;touch创建普通文件。用ls -al查看文件属性。 从上图可以看出目录或者文件的所有者#xff0c;所属组#xff0c;其他人权限#xff0c;创建时间等信息。由…1.文件 1.1文件属性 当我们创建文件时文件就有了对应的属性可以用mkdir创建目录touch创建普通文件。用ls -al查看文件属性。 从上图可以看出目录或者文件的所有者所属组其他人权限创建时间等信息。由此我们便可以得到一个结论文件创建出来即使我们没有写入任何的数据他也是有大小的。使用stat可以查看文件的详细信息。 stat test.c 这里大小显示为0并不是没有占内存而是大小不足一字节所以显示为0. 文件文件内容属性 1.2 文件存储位置 当文件没有被打开使用时如果把他放他被放置在系统的磁盘中但当文件打开时他就会被加载到内存中。CPU只会与内存进行数据处理使用文件前必须打开文件说的也就是把文件从磁盘加载到内存中让CPU进行数据处理。
1.3 文件与进程关系 当我们在修改文件时在Windows中会默认打开记事本在Linux中使用vim或者nano。实际上我们不会之间修改文件而是通过软件修改其实就是通过进程修改文件。我们要学习文件管理就是在学习OS进程管理与文件管理之间的关系。 1.4如何管理文件 一个进程可以打开多个文件多个进程可以打开很多文件在OS中这些文件分布在内存的各个地方为了管理这些文件Liunx必定会 先描述在组织。即在使用struct结构体包含文件信息然后再组织管理起来。如下图 在Liunx中学习文件操作就是学习进程管理与文件管理之间的关系。 2.C语言文件操作 在C语言中可以使用fopen打开文件fwritefputsfprintf等写入文件。
2.1 fopen path参数是文件地址可以采用绝对地址也可以采用想对地址。第二个参数是文件打开方式。函数失败返回空指针。
2.1.1 文件打开方式 文件打开方式主要有6种awr及其附加类 r 以只读方式打开文件(不可以修改文件)从文件开头读取。r 以读写方式打开文件从文件开头读取。w 以写方式打开文件文件存在清除不存在创建新文件从文件开头写入w 以写方式打开文件文件存在清除不存在创建新文件可以读取文件内容从文件开头写入a 以追加写入方式打开文件文件不存在则创建从文件结尾写入a 以追加读取写入方式打开文件文件不存在则创建从文件结尾写入。但读取从文件开头开始读取 总而言之C语言提供了丰富的文件接口使用。不同场景下使用合适的方式。
#includestdio.hint main()
{FILE * fpfopen(hello.txt,w);//不加路径则默认为当前路径下fprintf(fp,%s,hello files!\n);fclose(fp);return 0;
}运行上述程序后会在当前目录下生成hello.txt文件。 2.2 fclose 使用起来相对简单只需要把文件指针传入即可。 在打开文件后必须要关闭文件当我们在修改文件时文件数据是在内存中的如果直接结束进程内存中的数据被释放文件修改后的数据就可能不存在了。关闭文件实际上就是把在内存中的文件写入到磁盘当中去。 2.3 默认打开文件 当C语言程序运行时就会默认打开三个文件。
stdin 标准输入 一般为键盘stdout 标准输出 一般为显示器stderr 标准错误 一般为显示器 2.3.1 键盘与显示器为什么是文件 OS是软硬件资源的管理者对上要提供良好的开发环境对下要管理好硬件。实际上OS要管理好硬件就是要做好对于数据的IO操作从硬件读取数据或者是向硬件写入数据。 对于硬件来说他会有许多OS为了管理硬件一定会先描述在组织对下管理硬件资源。创建hardware_struct里面有设备名称硬件编号以及函数指针等。其中的函数指针就是为了读写操作准备的。 由此当我们想要向硬件写入的时候不必关注底层硬件设计只需要使用write函数即可剩下的交给硬件驱动。这就是Linux下的一切皆文件的实现方式。 实际上驱动程序主要就是IO操作相关的函数所以向电脑插入一个设备的时候电脑首先就会查看有没有相关的驱动程序如果没有就运行不了。我们之前学习的C语言函数就是对应上图的函数库操作。
3.系统文件操作 根据之前的操作系统图C语言函数一定是封装了系统调用接口的。OS不允许用户越过自己直接访问硬件。当然单片机除外简单的单片机没有OS
3.1 open open就是操作系统提供的打开文件操作。 int open(const char *pathname, int flags);该函数第一个参数是文件路径第二个参数是标记位可以选择对文件如何操作。有如下主要选项。
O_RDONLY以只读方式打开文件。O_WRONLY以只写方式打开文件。O_RDWR以读写方式打开文件。O_CREAT如果文件不存在则创建该文件。使用此标志时需要提供第三个参数 mode 来指定文件的权限。O_TRUNC如果文件存在且以可写方式打开则将文件截断为零长度。O_APPEND以追加方式打开文件每次写操作都会将数据追加到文件末尾。 上述标记位可以组合使用用 | 分隔开。例如O_WRONLY | O_CREAT | O_TRUNC 就可以达到C语言fopen中W的效果或者说C语言arw就是open不同选项封装的。
3.1.1 返回值 返回值是int没有看错返回值就是朴实无华的int。在Linux进程中我们必定要管理文件但是一个int类型怎么指向一个文件怎么根据int确定是那个文件。 运行下述代码。
#includestdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.hint main()
{int f1open(text1,O_WRONLY|O_CREAT);int f2open(text2,O_WRONLY|O_CREAT);int f3open(text3,O_WRONLY|O_CREAT);int f4open(text4,O_WRONLY|O_CREAT);int f5open(text5,O_WRONLY|O_CREAT);printf(f1:%d f2:%d f3:%d f4:%d f5:%d,f1,f2,f3,f4,f5);return 0;
}我们可以发现如果我们连续打开文件这是一连串的数字从3开始。计算机中有什么结构有如此规整的数字么答案显然是数组至于为什么从3开始因为我们每个进程默认打开三个文件标准输入标准输出标准错误。 实际上进程就是使用数组来管理文件的如下图。 3.1.2 标记位如何实现 实际上flags就是个32位的位图每个O_RDONLYO_WRONLY都是宏定义且是某个比特位为1的特殊值。如下图
#includestdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
int main()
{printf(%d %d %d %d\n,O_RDONLY,O_WRONLY, O_CREAT,O_TRUNC);return 0;
} |实际上就是按位或有1为1这样在传入参数后可以根据每个比特位的情况来实现不同的功能而避免写过多的函数。 3.1.3 open 在 C 语言里并没有像 C 那样的函数重载机制C 语言要求函数名必须唯一。不过在 Linux 系统中open 函数存在两种不同参数列表的形式这并非是通过函数重载实现的而是借助预处理器和编译器的协作来达成的。 int open(const char *pathname, int flags, mode_t mode);前两个参数与之前一样第三个参数是设置文件的权限。 这里使用数字实际上也是运用位图的思想每个选项对应一个比特位。 #include stdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.hint main() {open(hello.txt, O_TRUNC | O_WRONLY|O_CREAT, 0777);//这里0777表示8进制二进制为 0 111 111 111return 0;
}运行上述程序得到如下结果。 但看起来与我们设置的777不符合为0775这是因为还有掩码umask作用真实权限是将默认权限值与 umask 值按位取反的结果进行按位与运算。简单记位减去掩码就是真正的权限。权限open设置-掩码 111 111 111 默认权限 111 111 101 取反后的掩码位 --------------- 111 111 101 计算结果 3.2 close 这个是Linux系统提供的接口可以关闭文件他的参数比较特殊是fd就是文件在进程管理数组中的下标。关闭成功返回0失败返回-1. 标准输入标准输出标准错误也是文件在数组下标为012.一定也可以被关闭。如下代码。 #includestdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.hint main()
{close(2);int f1open(text1,O_WRONLY|O_CREAT);int f2open(text2,O_WRONLY|O_CREAT);int f3open(text3,O_WRONLY|O_CREAT);int f4open(text4,O_WRONLY|O_CREAT);int f5open(text5,O_WRONLY|O_CREAT);printf(f1:%d f2:%d f3:%d f4:%d f5:%d\n,f1,f2,f3,f4,f5);return 0;
}可以发现下标从2开始。在运行下述程序关闭0号文件。
#includestdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.hint main()
{close(0);int f1open(text1,O_WRONLY|O_CREAT);int f2open(text2,O_WRONLY|O_CREAT);int f3open(text3,O_WRONLY|O_CREAT);int f4open(text4,O_WRONLY|O_CREAT);int f5open(text5,O_WRONLY|O_CREAT);printf(f1:%d f2:%d f3:%d f4:%d f5:%d\n,f1,f2,f3,f4,f5);return 0;
} 此时下标从1开始由此我们可以得出下标的分配是从最小的没开始用的数组下标开始。