Linux应用编程和网络编程(3)------- Linux中文件的属性
目录
- 一,linux中各种文件类型
- 二,常用文件属性获取
- 三,文件权限管理
- 四,读取目录文件
一,linux中各种文件类型
1、普通文件(- regular file)
(1)文本文件。文件中的内容是由文本构成的,文本指的是ASCII码字符。文件里的内容本质上都是数字(不管什么文件内容本质上都是数字,因为计算机中本身就只有1和0),而文本文件中的数字本身应该被理解为这个数字对应的ASCII码。常见的.c文件, .h文件 .txt文件等都是文本文件。文本文件的好处就是可以被人轻松读懂和编写。所以说文本文件天生就是为人类发明的。
(2)二进制文件。二进制文件中存储的本质上也是数字,只不过这些数字并不是文字的编码数字,而是就是真正的数字。常见的可执行程序文件(gcc编译生成的a.out,arm-linux-gcc编译连接生成的.bin)都是二进制文件。
(3)对比:从本质上来看(就是刨除文件属性和内容的理解)文本文件和二进制文件并没有任何区别。都是一个文件里面存放了数字。区别是理解方式不同,如果把这些数字就当作数字处理则就是二进制文件,如果把这些数字按照某种编码格式去解码成文本字符,则就是文本文件。
(4)我们如何知道一个文件是文件文件还是二进制文件?在linux系统层面是不区分这两个的(譬如之前学过的open、read、write等方法操作文件文件和二进制文件时一点区别都没有),所以我们无法从文件本身准确知道文件属于哪种,我们只能本来就知道这个文件的类型然后用这种类型的用法去用他。有时候会用一些后缀名来人为的标记文件的类型。
(5)使用文本文件时,常规用法就是用文本文件编辑器去打开它、编辑它。常见的文本文件编辑器如vim、gedit、notepad++、SourceInsight等,我们用这些文本文件编辑器去打开文件的时候,编辑器会read读出文件二进制数字内容,然后按照编码格式去解码将其还原成文字展现给我们。如果用文本文件编辑器去打开一个二进制文件会如何?这时候编辑器就以为这个二进制文件还是文本文件然后试图去将其解码成文字,但是解码过程很多数字并不对应有意义的文字所以成了乱码。
(6)反过来用二进制阅读工具去读取文本文件会怎么样?得出的就是文本文字所对应的二进制的编码。
2、目录文件(d directory)
(1)目录就是文件夹,文件夹在linux中也是一种文件,不过是特殊文件。用vi打开一个文件夹就能看到,文件夹其实也是一种特殊文件,里面存的内容包括这个文件的路径,还有文件夹里面的文件列表。
(2)但是文件夹这种文件比较特殊,本身并不适合用普通的方式来读写。linux中是使用特殊的一些API来专门读写文件夹的。
3、字符设备文件(c character)
4、块设备文件(b block)
(1)设备文件对应的是硬件设备,也就是说这个文件虽然在文件系统中存在,但是并不是真正存在于硬盘上的一个文件,而是文件系统虚拟制造出来的(叫虚拟文件系统,如/dev /sys /proc等)
(2)虚拟文件系统中的文件大多数不能或者说不用直接读写的,而是用一些特殊的API产生或者使用的,具体在驱动阶段会详解。
5、管道文件(p pipe)
6、套接字文件(s socket)
7、符号链接文件(l link)
二,常用文件属性获取
1、stat、fstat、lstat函数简介
(1)每个文件中都附带了这个文件的一些属性(属性信息是存在于文件本身中的,但是它不像文件的内容一样可以被vi打开看到,属性信息只能被专用的API打开看到)
(2)文件属性信息查看的API有三个:stat、fstat、lstat,三个作用一样,参数不同,细节略有不同。
(3)linux命令行下还可以去用stat命令去查看文件属性信息,实际上stat命令内部就是使用stat系统调用来实现的。
(4)stat这个API的作用就是让内核将我们要查找属性的文件的属性信息结构体的值放入我们传递给stat函数的buf中,当stat这个API调用从内核返回的时候buf中就被填充了文件的正确的属性信息,然后我们通过查看buf这种结构体变量的元素就可以得知这个文件的各种属性了。
(5)fstat和stat的区别是:stat是从文件名出发得到文件属性信息结构体,而fstat是从一个已经打开的文件fd出发得到一个文件的属性信息。所以用的时候如果文件没有打开(我们并不想打开文件操作而只是希望得到文件属性)那就用stat,如果文件已经被打开了然后要属性那就用fstat效率会更高(stat是从磁盘去读取文件的,而fstat是从内存读取动态文件的)。
(6)lstat和stat/fstat的差别在于:对于符号链接文件,stat和fstat查阅的是符号链接文件指向的文件的属性,而lstat查阅的是符号链接文件本身的属性。
2、struct stat结构体简介
(1)struct stat是内核定义的一个结构体,在<sys/stat.h>中声明,所以我们可以用。这个结构体中的所有元素加起来就是我们的文件属性信息。
3、写个程序来查看一些常见属性信息
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>#define NAME "1.txt"int main(void)
{int ret = -1;struct stat buf;memset(&buf, 0, sizeof(buf)); // memset后buf中全是0ret = stat(NAME, &buf); // stat后buf中有内容了if (ret < 0){perror("stat");exit(-1);}// 成功获取了stat结构体,从中可以得到各种属性信息了printf("inode = %d.\n", buf.st_ino);printf("size = %d bytes.\n", buf.st_size);printf("st_blksize = %d.\n", buf.st_blksize);return 0;
}
实验结果:
4、用代码判断文件类型
(1)文件类型就是-、d、l····
(2)文件属性中的文件类型标志在struct stat结构体的mode_t st_mode元素中,这个元素其实是一个按位来定义的一个位标志(有点类似于ARM CPU的CPSR寄存器的模式位定义)。这个东西有很多个标志位共同构成,记录了很多信息,如果要查找时按位&操作就知道结果了,但是因为这些位定义不容易记住,因此linux系统给大家事先定义好了很多宏来进行相应操作。
(3)譬如S_ISREG宏返回值是1表示这个文件是一个普通文件,如果文件不是普通文件则返回值是0.
实验代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>#define NAME "1.txt"int main(void)
{int ret = -1;struct stat buf;memset(&buf, 0, sizeof(buf)); // memset后buf中全是0ret = stat(NAME, &buf); // stat后buf中有内容了if (ret < 0){perror("stat");exit(-1);} // 判断这个文件属性//int result = S_ISREG(buf.st_mode); //判断是否为普通文件,是则返回1,不是返回0int result = S_ISDIR(buf.st_mode); //判断是否为目录文件,是则返回1,不是返回0printf("result = %d\n", result);return 0;
}
结果:
三,文件权限管理
1、st_mode中记录的文件权限位
(1)st_mode本质上是一个32位的数(类型就是unsinged int),这个数里的每一个位表示一个含义。
(2)文件类型和文件的权限都记录在st_mode中。我们用的时候使用专门的掩码去取出相应的位即可得知相应的信息。
2、ls -l打印出的权限列表
(1)123456789一共9位,3个一组。第一组三个表示文件的属主(owner、user)对该文件的可读、可写、可执行权限;第2组3个位表示文件的属主所在的组(group)对该文件的权限;第3组3个位表示其他用户(others)对该文件的权限。
(2)属主就是这个文件属于谁,一般来说文件创建时属主就是创建这个文件的那个用户。但是我们一个文件创建之后还可以用chown命令去修改一个文件的属主,还可以用chgrp命令去修改一个文件所在的组。
3、文件操作时的权限检查规则
(1)一个程序a.out被执行,a.out中试图去操作一个文件1.txt,这时候如何判定a.out是否具有对1.txt的某种操作权限呢?
(2)判定方法是:首先1.txt具有9个权限位,规定了3种人(user、group、others)对该文件的操作权限。所以我们判定1.txt是否能被a.out来操作,准确的说是看a.out被谁执行,也就是当前程序(进程)是哪个用户的进程。
4、access函数检查权限设置
(1)access函数可以测试得到当前执行程序的那个用户在当前那个环境下对目标文件是否具有某种操作权限。
5、chmod/fchmod与权限修改
(1)chmod是一个linux命令,用来修改文件的各种权限属性。chmod命令只有root用户才有权利去执行修改。
(2)chmod命令其实内部是用linux的一个叫chmod的API实现的。
实践代码:
#include <stdio.h>
#include <sys/stat.h>int main(int argc, char **argv)
{int ret = -1;if (argc != 2){printf("usage: %s filename\n", argv[0]);return -1;}ret = chmod(argv[1], S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWOTH); //设置属主对文件有可读可写可执行权限if (ret < 0) //属主所在的组对文件有可读权限,其他用户对文件有可操作权限{perror("chmod");return -1;}return 0;
}
6、chown/fchown/lchown与属主修改
(1)linux中有个chown命令来修改文件属主
(2)chown命令是用chown API实现的
7、umask与文件权限掩码
(1)文件掩码是linux系统中维护的一个全局设置,umask的作用是用来设定我们系统中新创建的文件的默认权限的。
(2)umask命令就是用umask API实现的
四,读取目录文件
1、opendir与readdir函数
(1)opendir打开一个目录后得到一个DIR类型的指针给readdir使用
(2)readdir函数调用一次就会返回一个struct dirent类型的指针,这个指针指向一个结构体变量,这个结构体变量里面记录了一个目录项(所谓目录项就是目录中的一个子文件)。
(3)readdir调用一次只能读出一个目录项,要想读出目录中所有的目录项必须多次调用readdir函数。readdir函数内部户记住哪个目录项已经被读过了哪个还没读,所以多次调用后不会重复返回已经返回过的目录项。当readdir函数返回NULL时就表示目录中所有的目录项已经读完了。
2、读取目录实代码战
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>int main(int argc, char **argv)
{DIR *pDir = NULL;struct dirent * pEnt = NULL;unsigned int cnt = 0;if (argc != 2){printf("usage: %s dirname\n", argv[0]);return -1;}pDir = opendir(argv[1]);if (NULL == pDir){perror("opendir");return -1;}while (1){pEnt = readdir(pDir);if(pEnt != NULL){// 还有子文件,在此处理子文件printf("name:[%s] ,", pEnt->d_name);cnt++;if (pEnt->d_type == DT_REG){printf("是普通文件\n");}else{printf("不是普通文件\n");}}else{break;}};printf("总文件数为:%d\n", cnt);return 0;
}
3、可重入函数引入
(1)有些函数是可重入的有些是不可重入的,至于具体用法读者自行去百度查阅。
(2)readdir函数和我们前面接触的一些函数是不同的,首先readdir函数直接返回了一个结构体变量指针,因为readdir内部申请了内存并且给我们返回了地址。多次调用readdir其实readir内部并不会重复申请内存而是使用第一次调用readdir时分配的那个内存。这个设计方法是readdir不可重入的关键。
(3)readdir在多次调用时是有关联的,这个关联也标明readdir函数是不可重入的。
(4)库函数中有一些函数当年刚开始提供时都是不可重入的,后来意识到这种方式不安全,所以重新封装了C库,提供了对应的可重复版本(一般是不可重入版本函数名_r)
Linux应用编程和网络编程(3)------- Linux中文件的属性相关推荐
- 如何连接Linux上的服务器 网络编程,Linux 网络编程 一
一.网络编程基础 网络编程本身是一门很大的学问,涉及到的东西也很多,尤其是各种协议.先看图: 正如上图所示,网络编程中包含五大层面(也有区分六个层面),从应用层到物理层可以明显看出 越往下越接近计算机 ...
- linux应用编程和网络编程
注:本文是对朱老师linux应用编程和网络编程课程的备忘引导性笔记,主要是为了能够在学完后快速回忆起相关内容.本文主要记录了一些关键易忘性知识点并包含少量理解性内容,遵循尽量精简的原则,以尽量少的篇幅 ...
- 套接字编程-TCP网络编程
文章目录 套接字地址结构 通用套接字地址数据结构 以太网协议的套接字地址数据结构 Netlink协议套接字地址结构 TCP网络编程 套接字初始化socket() domain type protoco ...
- python socket编程_Python Socket编程实现网络编程
对于有经验的开发人员来说,掌握的编程语言应该是不少的.在这些编程语言中,网络编程的应用时必不可少的.其中Python也是这样的编程语言.我们今天将会在这里为大家详细介绍一下Python Socket编 ...
- 迈入JavaWeb第一步,Java网络编程基础,TCP网络编程URL网络编程等
文章目录 网络编程概述 网络通信要素 要素一IP和端口号 要素二网络协议 TCP网络编程 UDP网络编程 URL网络编程 Java网络编程基础 网络编程概述 Java是Internet上的语言,它从语 ...
- python 网络编程是什么_什么是网络编程-Python 网络编程-嗨客网
Python网络编程网络编程教程 网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机.数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一 ...
- Linux环境下的网络编程
本文介绍了在Linux环境下的socket编程常用函数用法及socket编程的一般规则和客户/服务器模型的编程应注意的事项和常遇问题的解决方法,并举了具体代 码实例.要理解本文所谈的技术问题需要读者 ...
- linux服务器开发三(网络编程)
转载自:http://www.cnblogs.com/zfc2201/archive/2017/05/04/6804990.html 作者:水之原 网络基础 协议的概念 什么是协议 从应用的角度出发, ...
- Linux学习路线及网络编程经典书籍
linux学习资源整理:https://zhuanlan.zhihu.com/p/22654634 Linux初学者(学习资料):https://zhuanlan.zhihu.com/p/217232 ...
- Linux学习之----socket网络编程基础
分层模型 OSI七层模型 1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后再转 ...
最新文章
- 购买阿里云服务器地域如何选择?
- 如果自己做事情,一直这样做会有一个缺点
- ML.NET 0.10特性简介
- aws lambda使用_使用AWS Lambda的CloudWatch事件通知
- 获得诺贝尔奖之后影响力会下降?绘制精英科学家的职业生涯路线图
- centos7搭建easy-mock服务
- 织梦CMS调用文章列表时,怎么显示短时间格式
- Runtime Message Forwarding
- Atitit it sftwr dev 原则准则 principle 目录 第一章 简单原则 kiss	1 第一节 . You Ain’t Gonna Need It(YAGNI)避免过度设计	1
- 威纶通触摸屏上传错误_威纶通触摸屏程序怎么上传?
- Excel函数(4)日期、文本函数
- ZZNUOJ_C语言1083:数值统计(多实例测试)(完整代码)
- 我要偷偷的学Python,然后惊呆所有人(第五天)
- 什么是EasyUI,如何使用EasyUI?--easyui的十二种用法
- pixi.js 实现Sprite跟随鼠标移动
- 买礼物(线段树+set维护)
- 权限控制-Shiro
- Android版股票K线图实现方案
- 蛋白质相互作用位点标签的获取方法
- amazon账号注册用什么软件?