文件IO——获取文件属性

以下内容源于朱有鹏嵌入式课程的学习整理与整理,如有侵权请告知删除。

前言

文件属性,包括文件的名字、创建时间、文件类型、文件权限等等内容。

本文讲述了以下内容:

(1)文件类型有哪些;

(2)文件权限管理的内容;

(3)利用stat函数获取某个文件的属性信息;

(4)操作目录文件。

一、文件类型

文件类型符号标识
普通文件 (regular file)-
目录文件(directory)d
字符设备文件(character)c
块设备文件(block)b
管道文件(pipe)p
套接字文件(socket)s
符号链接文件(link)l

1、普通文件

1)普通文件包括:文本文件、二进制文件。

文本文件,是由ASCII码字符构成的文件。常见的.c文件、.h文件、.txt文件等都是文本文件,它可以被人轻松读懂和编写,是为人类而发明的。其实文本文件本质上还是由数字01构成的文件,不过编辑器读出这些数字后,按照编码格式转化成ASCII字符。

二进制文件,是有01数字构成的文件,不过01数字不是某些字符的编码,而是真正的数字。常见的可执行程序文件,比如由gcc编译生成的a.out、arm-linux-gcc编译连接生成的.bin文件,都是二进制文件。

2)如何区别二进制文件和文本文件?

从本质上来看,文本文件和二进制文件并没有任何区别,都是一个文件里面存放了数字。如果把这些数字就当作数字处理则就是二进制文件,如果把这些数字按照某种编码格式去解码成文本字符,则就是文本文件。

Linux系统不区分这两种文件,比如open、read、write等方法操作文本文件和二进制文件时,没有一点区分。为了明确文件类型,有时候人为地添加后缀来表征文件类型。

3)如何打开与编辑?

常见的文本文件编辑器如vim、gedit、notepad++、SourceInsight等;使用这些文本文件编辑器去打开文件的时候,编辑器读出文件二进制数字内容,然后按照编码格式去解码将其还原成文字。

如果用文本文件编辑器去打开一个二进制文件,编辑器以为这个二进制文件还是文本文件,然后试图去将其解码成文字,但是解码过程很多数字并不对应有意义的文字,所以成了乱码。

如果用二进制阅读工具去读取文本文件,得到的就是文本文字所对应的二进制的编码。

2、目录文件

目录文件即文件夹,文件夹在linux中也是一种文件,不过是特殊文件。

用vi打开一个文件夹,可知文件夹里的内容包括这个文件夹的路径、文件夹里面的文件列表。

linux中使用特殊的一些API读写文件夹。

3、块设备文件

设备文件对应的是硬件设备。

它不是真正存在于硬盘上的一个文件,而是由文件系统虚拟制造出来的。

虚拟文件系统中的文件,需要用一些特殊的API产生或者使用。

二、文件权限

文件权限,指不同用户的读写与执行权限。

1、“ls -l”命令

使用“ls -l”命令打印出来的信息,比如“- rwx rwx rwx”,其中“-”表示文件类型(这里表示普通文件);从左到右,第一组“rwx”表示文件属主对该文件的操作权限,第二组表示文件属主所在组队该文件的操作权限,第三组表示其他用户对该文件的操作权限。

2、access函数

函数原型

 int access(const char *pathname, int mode);

函数作用

该函数用来检测当前用户对文件是否具有某种操作权限。

补充说明

mode的可取值分别为:R_OK、W_OK、X_OK、F_OK。它们分别用来测试是否可读、是否可写、是否可执行、文件是否存在。 

3、chmod函数

只有root用户才能使用chmod命令,该命令实际调用的是Linux内部一个叫做chmod的API。

函数原型

int chmod(const char *path, mode_t mode);

函数作用

该函数用来修改文件的权限

补充说明

(1)chmod命令的细节:chmod命令:修改文件(夹)权限_天糊土的博客-CSDN博客

(2)mode的可选值及其含义

S_IRUSR  (00400)  read by owner

S_IWUSR  (00200)  write by owner

S_IXUSR  (00100)  execute/search  by  owner ("search" applies for directories, and means that entries within the directory can be accessed)

S_IRGRP  (00040)  read by group

S_IWGRP  (00020)  write by group

S_IXGRP  (00010)  execute/search by group

S_IROTH  (00004)  read by others

S_IWOTH  (00002)  write by others

S_IXOTH  (00001)  execute/search by others

代码示例

ret=chmod(argv[1] ,S_IRUSR | S_IWUSR | S_IXUSR)

三、获取文件属性

1、stat函数的介绍

每个文件都具有一些属性(比如文件类型、文件权限等等),这些属性存在于文件本身,只能被一些专用的API打开看到,比如stat、fstat、lstat,它们作用一样,参数不同,细节略有不同。这里重点简述stat这个API。

在命令行中,使用命令“man 1 stat”以及“man 2 stat”,都可以得到stat的使用手册。这说明stat是linux下的一个命令,同时也是linux下的API(或者说函数),或者说stat命令就是通过stat这个API来实现的。

xjh@ubuntu:~/iot/tmp$ stat sample.c File: ‘sample.c’Size: 169       	Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d	Inode: 917861      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     xjh)   Gid: ( 1000/     xjh)
Access: 2022-06-17 23:47:02.105965691 +0800
Modify: 2022-06-17 23:29:15.993972099 +0800
Change: 2022-06-17 23:29:15.997972099 +0800Birth: -
xjh@ubuntu:~/iot/tmp$ //上面的IO BLOCK 表示达到多少内容时,缓冲区的内容才会写入硬盘

stat函数的模型

 int stat(const char *path, struct stat *buf);

stat函数的作用

内核将某个文件的属性信息结构体填充到stat函数的参数buf所指向的结构体中(这个参数是不加const修饰的指针,说明它是输出型参数),当stat这个API调用从内核返回时,buf所指向的结构体就被文件的属性信息填充好了。

我们后续通过查看buff结构体变量的元素,就可以得知该文件的各种属性。比如:

#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;//struct stat buf={0};初始化方法1,或者使用下面的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;
}

参数说明

struct stat是内核定义的一个结构体,在<sys/stat.h>中声明。 这个结构体中的所有元素加起来就是文件属性信息。

 struct stat {dev_t     st_dev;     /* ID of device containing file */ino_t     st_ino;     /* inode number */mode_t    st_mode;    /* protection */nlink_t   st_nlink;   /* number of hard links */uid_t     st_uid;     /* user ID of owner */gid_t     st_gid;     /* group ID of owner */dev_t     st_rdev;    /* device ID (if special file) */off_t     st_size;    /* total size, in bytes */blksize_t st_blksize; /* blocksize for filesystem I/O */blkcnt_t  st_blocks;  /* number of 512B blocks allocated */time_t    st_atime;   /* time of last access */time_t    st_mtime;   /* time of last modification */time_t    st_ctime;   /* time of last status change */};

补充说明

stat和stat的区别

  • stat是从文件名出发得到文件属性信息结构体,而fstat是从一个已经打开的文件fd出发,得到一个文件的属性信息;
  • 如果文件没有打开就用stat,如果文件已经被打开用fstat效率会更高。因为stat是从磁盘去读取文件的,而fstat是从内存读取动态文件的。

lstat和stat/fstat的差别

  • 对于符号链接文件,stat和fstat查阅的是符号链接文件指向的文件的属性,而lstat查阅的是符号链接文件本身的属性。

2、stat函数的应用案例

(1)获知文件类型

文件类型标志在struct stat结构体的 st_mode 元素中。

  • st_mode本质上是一个32位的数(类型就是unsinged int),这个数里的每一个位表示一个含义,按位&操作可以知道某些信息。
  • 但是这些位定义不容易记住,因此linux系统事先定义很多宏来进行相应操作。
  • 比如S_ISREG宏返回值是1表示这个文件是一个普通文件,如果文件不是普通文件则返回值是0;
The following POSIX macros are defined to check \the file type using the st_mode field:S_ISREG(m)  is it a regular file?S_ISDIR(m)  directory?S_ISCHR(m)  character device?S_ISBLK(m)  block device?S_ISFIFO(m) FIFO (named pipe)?S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

2)获知文件权限

st_mode中除了记录文件类型,还记录着一个重要信息:文件权限。

linux并没有给文件权限测试提供宏操作,只提供了位掩码,所以我们只能用位掩码来判断是否具有相应权限。

 The following flags are defined for the st_mode field:S_IFMT     0170000   bit mask for the file type bit fieldsS_IFSOCK   0140000   socketS_IFLNK    0120000   symbolic linkS_IFREG    0100000   regular fileS_IFBLK    0060000   block deviceS_IFDIR    0040000   directoryS_IFCHR    0020000   character deviceS_IFIFO    0010000   FIFOS_ISUID    0004000   set-user-ID bitS_ISGID    0002000   set-group-ID bit (see below)S_ISVTX    0001000   sticky bit (see below)S_IRWXU    00700     mask for file owner permissionsS_IRUSR    00400     owner has read permissionS_IWUSR    00200     owner has write permissionS_IXUSR    00100     owner has execute permissionS_IRWXG    00070     mask for group permissionsS_IRGRP    00040     group has read permissionS_IWGRP    00020     group has write permissionS_IXGRP    00010     group has execute permissionS_IRWXO    00007     mask for permissions for others (not in group)S_IROTH    00004     others have read permissionS_IWOTH    00002     others have write permissionS_IXOTH    00001     others have execute permission

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);}#if 0	// 判断这个文件属性int result = S_ISDIR(buf.st_mode);printf("result = %d\n", result);
#endif// 文件权限测试unsigned int result = ((buf.st_mode & S_IRUSR)? 1: 0);printf("file owner: %u.\n", result);return 0;
}

三、对目录文件的操作

(1)opendir函数与readdir函数

对于目录文件,我们一般先使用opendir函数打开目录文件,然后再使用readdir函数读取目录文件。

在命令行中输入“man 3 opendir”、“man 3readdir”,可以知道这两个函数的模型:

DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);

使用opendir函数打开一个目录后,得到一个DIR类型的指针给readdir使用。

每调用一次readdir函数,就会返回一个struct dirent类型的指针,它记录着目录中的一个文件。要想读出目录中所有的文件,必须多次调用readdir函数。当readdir函数返回NULL时就表示目录中所有的文件都已经被读完了。另外,readdir函数内部户会对已经读过的文件进行记录,因此不会重复返回已经返回过的文件。

(2)struct dirent 结构体

struct dirent {ino_t          d_ino;       /* inode number */off_t          d_off;       /* not an offset; see NOTES */unsigned short d_reclen;    /* length of this record */unsigned char  d_type;      /* type of file; not supportedby all filesystem types */char           d_name[256]; /* filename */
};

(3)代码示例

将下面的代码用gcc编译生成a.out文件,然后在命令行输入“./a.out xxx”,其中xxx表示某个目录。

#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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用juniversalchardet做字符编码识别

为什么80%的码农都做不了架构师&#xff1f;>>> 在抓取网站的页面的时候最烦人的一件事情之一就是识别原站点的编码&#xff0c;通常来说只有GBK&#xff08;GB2312&#xff09;和UTF8两种&#xff0c;不过依旧需要读取大量Http头信息来识别&#xff0c;有些网站则…

淘宝开放API,很不错

http://api.taobao.com/myresources/standardSdk.htm?spm0.0.0.0.YeOZMs# 转载于:https://www.cnblogs.com/tandychao/archive/2013/03/01/2938561.html

短线操作总结

今日操作很失败&#xff0c;到嘴的肉都跑了&#xff01;首先是昨日上午买入的保险股&#xff0c;下午领涨&#xff0c;由于是T1的缘故&#xff0c;只能在今天卖&#xff0c;没想到今日保险股全线熄火&#xff0c;走了一波过山车&#xff0c;至尾盘微利&#xff1b;其次是昨天下…

新人报道,写的东西还请大神们多指导!也希望能让和我一样的同事少走弯路。...

大家好&#xff01;我刚工作&#xff0c;经验还很有限&#xff0c;写的东西都是自己在工作过程中遇到的问题&#xff0c;花了很多时间来解决之后的一些总结&#xff0c;可能比较浅显也比较简单&#xff0c;有什么不足的地方还请大家指正&#xff0c;有好的方法也欢迎大家留言&a…

如何用word制作英语答题卡_英语考试答题卡(word 版)

西宁联想教育培训学校西宁联想教育培训学校第1页共1页****学校****考试模拟试卷英语卷(答题卡)(时间&#xff1a;120分钟&#xff0c;满分&#xff1a;120分)姓名&#xff1a;_______________学校&#xff1a;___________________准考证号&#xff1a;________________________…

获取系统信息1——linux系统中的时间

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、关于时间的概念 1、GMT时间 GMT是格林尼治时间&#xff0c;即格林尼治地区的当地时间。用格林尼治的当地时间作为全球国际时间&#xff0c;用以描述全球性的事件的时间&#xff0c;方便大家记忆…

hystrix 单独使用_使用Hystrix对Dubbo消费者提供线程隔离保护

在dubbo中对于消费者的保护提供了actives进行并发控制保护&#xff0c;但是功能相对薄弱&#xff0c;下面我们探讨下如何使用Netflix提供的服务容错组件Hystrix对dubo消费者提供线程隔离保护为什么需要Hystrix?在大中型分布式系统中&#xff0c;通常我们需要依赖很多dubbo服务…

二分查找(Binary Search)

1.递归实现 int binarySearchRecursive(int a[],int low,int high,int key){if(low>high)return -(low1);int midlow(high-low)/2;if(key<a[mid])return binarySearchRecursive(a,low,mid-1,key);else if(key > a[mid])return binarySearchRecursive(a,mid1,high,key)…

判断一个字符串是否为回文-链队(新建,进队,出队),链栈(新建,进栈,出栈)...

回文&#xff1a;字符对称排列的字符串&#xff0c;例如ABCBA 思路&#xff1a;根据队&#xff1a;先进先出和栈: 先进后出的原则&#xff0c;进行比较出队和出栈的字符是否相等。如果相等&#xff0c;则为回文。 创建控制台应用程序。 1 #region 字符节点类 2 …

字符设备驱动基础5——驱动如何操控硬件

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 补充内容&#xff1a;字符设备驱动高级篇5——静态映射表、动态映射结构体方式操作寄存器 前言 上节字符设备驱动基础4——读写接口的操作实践中&#xff0c;驱动源代码中的test_chrdev_open()、te…

Android----使用代码 建立gprs 闹钟 连接

Android&#xff1a;实用代码&#xff08;开启启动、建立GPRS连接、闹钟等&#xff09; 分类&#xff1a; Android2012-04-21 18:06312人阅读评论(0)收藏举报androidactionstringservice手机j2me1&#xff1a;查看是否有存储卡插入String statusEnvironment.getExternalStorage…

句法依存分析_复旦大学邱锡鹏教授:词法、句法分析研究进展综述

本文为第十六届自然语言处理青年学者研讨会 YSSNLP2019 报告《词法、句法分析研究进展综述》的简要文字整理&#xff0c;本报告主要回顾词法、句法领域的最新研究进展。 关于报告人&#xff1a;邱锡鹏&#xff0c;复旦大学计算机科学技术学院副教授&#xff0c;博士生导师。于复…

【struts2】Struts2的运行流程

1&#xff09;前提条件 在讲解流程之前&#xff0c;假设我们已经建立了的一个名为strutsDeepen的web工程&#xff0c;该工程仅仅实现了简单的用户登陆与欢迎界面。具体的实现为&#xff1a; 在web.xml中配置了Struts2的过滤器写了一个Action类&#xff0c;名称为loginAction在s…

获取系统信息2——linux中使用随机数

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、随机数和伪随机数 随机数是随机出现&#xff0c;没有任何规律的一组数列。真正的完全随机的数列是不存在的&#xff0c;只是一种理想情况。我们一般只能通过一些算法得到一个伪随机数序列。平时…

11. 类对象简介

11. 类对象简介1.1 类是一个模板&#xff0c;是一种类型&#xff0c;“物以类聚”1.2 对象是类的一个具体实现1.3例如&#xff1a;汽车模型和生产出来的汽车猫和我家的那只猫1.4 实例人骑车public class Test3{public static void main(String[] args){Person p new Person();…

python 建筑计算_制图小技巧:巧用Python和ELK瞬间完成总图建筑名称标注

哎呦&#xff0c;又到了每周一次的制图教室啦。经过前面两次制图教程的分享&#xff0c;相信大家对于白模填色和写实渲染这两种表达方式肯定有了较好的掌握。那么今天我们就转战制图技巧篇&#xff0c;和童鞋们聊一下总平面图中的建筑名称标注问题。对于总平面图&#xff0c;各…

在MacOSX上重新安装Python (10.8) python 自然语言处理的前戏

因为想学python自然语言处理就想在mac上重新配置一下python。 在网上找了很久才找到两篇有用的教程http://765i.cn/%E5%9C%A8macosx%E4%B8%8A%E9%87%8D%E6%96%B0%E5%AE%89%E8%A3%85python-10-8/ http://woodpecker.org.cn/diveintopython3/installing-python.html 第一篇文章基…

获取系统信息3——proc文件系统介绍和使用

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、proc文件系统介绍 1、操作系统级别的调试一般很困难 简单的程序可以单步调试&#xff1b;复杂一点的程序可以printf、cout等打印信息调试&#xff08;即输出信息到控制台&#xff09;&#xff0…

阻止函数源码在控制台输出

这是一个很贱的技能&#xff0c;我在谷歌控制台源码里看到的。相信大家都知道&#xff0c;在控制台里只输入函数名&#xff0c;不输入 () 然后按回车&#xff0c;就可以输出源码。 都不会陌生吧&#xff0c;这也有助于我们调试&#xff0c;是个很棒的技巧。不过系统内置的就会输…

值不值得入手_iPhone11现在还值不值得入手?真实用户说出心里话

iPhone11作为苹果走量的一款机型&#xff0c;自发布以来就备受争议&#xff0c;有的朋友说真香&#xff0c;A13iOS只卖4000多&#xff0c;还有的朋友吐槽大黑边、828P的屏幕、信号不好还有充电太慢&#xff0c;特别是现在同价位能买到的安卓旗舰&#xff0c;要5G有5G、要高刷新…