IO学习系列之使用文件IO的接口在一个目录下,实现Linux命令“ls -l”的功能

  • 实例要求:
  • 使用文件IO的接口在一个目录下,实现Linux命令“ls -l”的功能;
  • 实例分析:
  • 正常使用“ls -l”命令,会出现以下内容:
/*-    rwxrw-rw-                                1          linux      linux          26                10月2 14:31    x.txt
文件类型  所属用户的权限\所属组的权限\其他人的权限 硬链接个数  所属用户    所属组      大小(字节)       时间戳       文件名
*/
  • 相关的文件IO接口函数如下:
  • opendir函数:
	 #include <sys/types.h>#include <dirent.h>DIR *opendir(const char *name);/*功能:打开一个目录文件参数name:目录名返回值:成功:  目录指针失败:  NULL 重置错误码*/
  • readdir函数:
	 #include <dirent.h>struct dirent *readdir(DIR *dirp);/*功能:读取目录下的内容参数:目录指针返回值:成功:  dirent结构体指针失败:  NULL  重置错误码*/// dirent结构体指针struct dirent {ino_t          d_ino;       /* 读到的文件的inode号 */off_t          d_off;       /* 无需关注 */unsigned short d_reclen;    /* 这个结构体的大小 不是文件的大小 */unsigned char  d_type;      /* 文件类型 */DT_BLK      This is a block device.DT_CHR      This is a character device.DT_DIR      This is a directory.DT_FIFO     This is a named pipe (FIFO).DT_LNK      This is a symbolic link.DT_REG      This is a regular file.DT_SOCK     This is a UNIX domain socket.char           d_name[256]; /* 文件名 */};
  • closedir函数:
	#include <sys/types.h>#include <dirent.h>int closedir(DIR *dirp);/*功能:关闭一个目录参数dirp:目录指针返回值:成功:  0失败:  -1  重置错误码*/
  • stat函数:
	#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>int stat(const char *pathname, struct stat *statbuf);/*功能:获取文件的属性信息参数:pathname:文件的路径和名字statbuf:用来保存文件属性的结构体返回值:成功  0失败  -1  重置错误码*///文件属性的结构体struct stat {dev_t     st_dev;         /* 文件所在磁盘的设备号 */ino_t     st_ino;         /* inode号 */mode_t    st_mode;        /* 文件的类型和访问模式 *///S_IFMT     0170000   文件类型的掩码//S_IFSOCK   0140000   socket//S_IFLNK    0120000   symbolic link//S_IFREG    0100000   regular file//S_IFBLK    0060000   block device//S_IFDIR    0040000   directory//S_IFCHR    0020000   character device//S_IFIFO    0010000   FIFO  if((S_IFMT & st_mode) == S_IFREG){//注意优先级问题printf("普通文件\n");}//或者用下面的宏判断if(S_ISREG(m)){printf("普通文件\n");}//st_mode & 0777 == 文件的权限nlink_t   st_nlink;       /* 硬链接的个数 */uid_t     st_uid;         /* 所属用户的id */gid_t     st_gid;         /* 所属组的id */dev_t     st_rdev;        /* 设备号 字符设备文件或者块设备文件使用 */off_t     st_size;        /* 总大小 单位字节 */blksize_t st_blksize;     /* 块的大小 */blkcnt_t  st_blocks;      /* 块的数量 */struct timespec st_atim;  /* 最后一次访问的时间 */struct timespec st_mtim;  /* 最后一次修改的时间 */struct timespec st_ctim;  /* 最后一次状态改变的时间 *///下面的宏定义是为了方便获取时间戳里的秒数的#define st_atime st_atim.tv_sec      /* Backward compatibility */#define st_mtime st_mtim.tv_sec#define st_ctime st_ctim.tv_sec};
  • getpwuid函数:
	#include <sys/types.h>#include <pwd.h>struct passwd *getpwuid(uid_t uid);/*功能:根据uid获取用户信息参数:uid: 用户id返回值:成功: 	用户信息结构体失败:  	NULL  重置错误码*///用户信息结构体struct passwd {char   *pw_name;       /* username */char   *pw_passwd;     /* user password */uid_t   pw_uid;        /* user ID */gid_t   pw_gid;        /* group ID */char   *pw_gecos;      /* user information */char   *pw_dir;        /* home directory */char   *pw_shell;      /* shell program */};
  • getgrgid函数:
	 #include <sys/types.h>#include <grp.h>struct group *getgrgid(gid_t gid);/*功能:根据gid获取组信息参数:gid: 组id返回值:成功 组信息结构体失败  NULL  重置错误码*/struct group {char   *gr_name;        /* group name */char   *gr_passwd;      /* group password */gid_t   gr_gid;         /* group ID */char  **gr_mem;         /* NULL-terminated array of pointers to names of group members */};
  • sprintf函数:
	#include <stdio.h>int sprintf(char *str, const char *format, ...);/*功能:将格式化的信息写入str指向的缓冲区中参数:str:		自定义的缓冲区的首地址format:	格式...:		可变参返回值:成功:  		格式化的字符的个数失败:  		小于0的值*/
  • 示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>//所属用户权限宏定义
#define U_R 0400
#define U_W 0200
#define U_X 0100//所属组权限宏定义
#define G_R 0040
#define G_W 0020
#define G_X 0010//其他人权限宏定义
#define O_R 0004
#define O_W 0002
#define O_X 0001int main(int argc, const char *argv[])
{//入参合理性检查if (2 != argc){printf("Usage : %s dir_name\n", argv[0]);return -1;}// 打开目录DIR *my_dir = opendir(argv[1]);if (NULL == my_dir){perror("opendir error");return -1;}//文件的类型char type = '-';//所属用户权限赋初值char u_r = '-';char u_w = '-';char u_x = '-';//所属组权限赋初值char g_r = '-';char g_w = '-';char g_x = '-';//其他人权限赋初值char o_r = '-';char o_w = '-';char o_x = '-';int nlink = 0;char u_name[64] = {0};char g_name[64] = {0};int size = 0;char date[128] = {0};char path_name[512] = {0};struct tm *p = NULL;struct stat lk;struct dirent *dir = NULL;int mode = 0;while (NULL != (dir = readdir(my_dir))){   //过滤隐藏文件if ('.' == *(dir->d_name)){continue;}//文件类型switch (dir->d_type){case DT_BLK:type = 'b';break;case DT_SOCK:type = 's';break;case DT_FIFO:type = 'p';break;case DT_REG:type = '-';break;case DT_LNK:type = 'l';break;case DT_CHR:type = 'c';break;case DT_DIR:type = 'd';break;}//数组清零memset(path_name, 0, sizeof(path_name));//组装路径sprintf(path_name, "%s/%s", argv[1], dir->d_name);if (stat(path_name, &lk)){perror("stat error");return -1;}u_r = '-';u_w = '-';u_x = '-';g_r = '-';g_w = '-';g_x = '-';o_r = '-';o_w = '-';o_x = '-';// 文件权限mode = lk.st_mode & 0777;if (mode & U_R){u_r = 'r';}if (mode & U_W){u_w = 'w';}if (mode & U_X){u_x = 'x';}if (mode & G_R){g_r = 'r';}if (mode & G_W){g_w = 'w';}if (mode & G_X){g_x = 'x';}if (mode & O_R){o_r = 'r';}if (mode & O_W){o_w = 'w';}if (mode & O_X){o_x = 'x';}//硬链接的个数nlink = lk.st_nlink;//所属用户名strcpy(u_name, getpwuid(lk.st_uid)->pw_name);//所属组名strcpy(g_name, getgrgid(lk.st_gid)->gr_name);//文件的大小(字节)size = lk.st_size;//时间戳(最后一次修改的时间)p = localtime(&(lk.st_mtime));sprintf(date, "%2d月%2d %02d:%02d", p->tm_mon + 1, \p->tm_mday, p->tm_hour, p->tm_min);//输出文件的基本内容printf("%c%c%c%c%c%c%c%c%c%c %d %s %s %7d %s %-s\n",\type, u_r, u_w, u_x, g_r, g_w, g_x, o_r, o_w, o_x, nlink,\u_name, g_name, size, date, dir->d_name);}// 关闭目录closedir(my_dir);return 0;
}
  • 运行结果:
linux@ubuntu:~$ ./a.out ./
-rw-rw-r-- 1 linux linux     730 101 22:44 k1.c
-rw-rw-r-- 1 linux linux      26 101 22:40 k2.txt
-rwxrwxr-x 1 linux linux   12984 102 19:31 a.out
-rw-rw-r-- 1 linux linux    4078 102 19:17 ls-l.c
drwxrwxr-x 2 linux linux    4096 102 18:59 k3
linux@ubuntu:~$ ls -l
总用量 32
-rwxrwxr-x 1 linux linux 12984 102 19:31 a.out
-rw-rw-r-- 1 linux linux   730 101 22:44 k1.c
-rw-rw-r-- 1 linux linux    26 101 22:40 k2.txt
drwxrwxr-x 2 linux linux  4096 102 18:59 k3
-rw-rw-r-- 1 linux linux  4078 102 19:17 ls-l.c
  • 本示例代码,仅供参考;

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

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

相关文章

stm32 - 中断/定时器

stm32 - 中断/定时器 概念时钟树定时器类型基准时钟&#xff08;系统时钟&#xff09;预分频器 - 时基单元CNT计数器 - 时基单元自动重装寄存器 - 时基单元基本定时器结构通用定时器计数器模式内外时钟源选择 定时中断基本结构时序预分频器时序计数器时序 概念 时钟树 https:…

FFmpeg 多图片合成视频带字幕和音乐+特效(淡入淡出,圆圈黑色淡出)

FFmpeg 多图片合成视频带字幕和音乐+特效(淡入淡出,圆圈黑色淡出) 效果图1. 报错及解决2. xfade、xfade_opeccl 特效切换3. ffmpeg命令行详解4. 源码4.1 auto.bash4.2 geneFade.py4.3 python moviepy合并视频及音频按照(视频长度截取对应的音频在合并)4.4 命令行记录参考这…

微信小程序一对多个页面间传递数据进行通信,事件触发的实现方法

在有些场景下&#xff0c;使用组件间通信或者组件和页面间通信并不可行。比如我需要只有一个websocket实例&#xff0c;并且需要向多个页面传递我接收到的消息。 下面的方法是一个页面向其它页面&#xff08;触发事件&#xff09;传递数据&#xff0c;其它页面也可以向这个页面…

变量和数据类型代码练习

案例一 /*编程实现变量的输入输出*/ //导入java目录中util目录的Scanner类 import java.util.Scanner; public class VarIOTest {public static void main (String args [] ) {// 1.声明两个变量用于记录姓名和年龄信息&#xff08;局部变量需要默认值&#xff09;//Sting na…

Vue中如何进行多语言处理

Vue中的多语言处理 在开发多语言Web应用程序时&#xff0c;处理文本翻译和国际化是一个重要的任务。Vue.js提供了多种方法来实现多语言处理&#xff0c;以确保您的应用程序能够支持不同语言的用户。本文将深入探讨在Vue中进行多语言处理的方法&#xff0c;并提供示例代码来帮助…

WebSocket基础——WebSocket的基本概念 VS Http SpringBoot整合WebSocket vue前端代码和效果展示

前言 WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它允许在单个TCP连接上进行双向通信&#xff0c;而不需要通过多个HTTP请求-响应循环来实现。相比传统的HTTP请求&#xff0c;WebSocket提供了更低的延迟和更高的实时性。 本篇博客介绍WebSocket的基本概念…

Linux shell编程学习笔记6:查看和设置变量的常用命令

上节我们介绍了变量的变量命名规则、变量类型、使用变量时要注意的事项&#xff0c;今天我们学习一下查看和设置变量的一些常用命令&#xff0c;包括变量的提升&#xff0c;有些命令在之前的实例中已经使用过了。 一、 echo &#xff1a;查看变量的值 语法格式&#xff1a;ech…

计算机毕业设计 基于SSM的垃圾分类管理系统(以医疗垃圾为例)的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

《发现的乐趣》作者费曼(读书笔记)

目录 一、书简介 二、作者理查德•费曼 费曼式思维 教育与传承 三、个人思考 四、笔记 科学家眼中的花之美 关于偏科 父亲教育我的方式 知道一个概念和真正懂得这个概念有很大区别 我没有义务去成全别人对我的期望 诺贝尔奖——够格吗&#xff1f; 探究世界的游戏规…

2023年汉字小达人市级比赛在线模拟题来了,四种练习助力好成绩

2023年第十届汉字小达人比赛区级自由报名活动已于9月30日结束&#xff0c;尽管最终晋级市级比赛的名单还需要在11月初发布&#xff08;有一些学校的校级选拔还没结束&#xff09;&#xff0c;但是许多小朋友已经开始准备市级比赛了。 根据往年的经验&#xff0c;实际比赛也是在…

接口测试入门实践

简单接口搭建(表单/REST) 五步教会你写接口 首先要安装flask包: pip install flask 从flask中导入Flask类和request对象: from flask import Flask, request从当前模块实例化出一个Flask实例:appFlask(__name__)编写一个函数来处理请求 从请求对象中获取数据:arequest.values.…

红黑树(有图解)

目录 介绍 概念 性质 模拟实现 结点定义 插入 保证平衡的原因 一般情况 特殊情况(uncle为黑) uncle不存在 旋转方式 右旋 迭代器 -- 代码 介绍 概念 红黑树是一种自平衡的二叉搜索树 它是在每个节点上引入额外的颜色信息,通过对任何一条从根到叶子的路径…

基于Dijkstra、A*和动态规划的移动机器人路径规划(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

优先级队列的模拟实现

目录 1. 优先级队列的概念 1.1堆的概念 1.2堆的性质 1.3堆的存储方式 2. 堆的创建 2.1堆的创建代码解析 2.2建堆的时间复杂度 2.3堆的插入 2.4 堆的删除 2.5常见习题 1. 优先级队列的概念 队列是一种先进先出 (FIFO) 的数据结构 &#xff0c;但有些情况下&#xff0c; 操作的数…

Windows下载AOSP

关于repo repo只是谷歌做的&#xff0c;方便下载安卓源码的工具&#xff0c;本质上是对下载清单进行批量处理&#xff0c;然后使用git克隆。 在windows上下载源码只需要自己处理即可。 具体做法 首先使用git克隆安卓源码清单 git clone https://mirrors.tuna.tsinghua.edu.…

chatgpt技术总结(包括transformer,注意力机制,迁移学习,Ray,TensorFlow,Pytorch)

最近研读了一些技术大咖对chatgpt的技术研讨&#xff0c;结合自己的一些浅见&#xff0c;进行些许探讨。 我们惊讶的发现&#xff0c;chatgpt所使用的技术并没有惊天地泣鬼神的创新&#xff0c;它只是将过去的技术潜能结合现在的硬件最大化的发挥出来&#xff0c;也正因如此&am…

2. selenium学习

Selenium 学习 简介 Selenium 是一个用于自动化浏览器的工具&#xff0c;它提供了多种编程语言的支持&#xff0c;包括 Python、Java、C# 等。它可以模拟用户在浏览器中的操作&#xff0c;比如点击按钮、填写表单、提交数据等。Selenium 具有强大的功能和灵活的定制性&#x…

C# 画参数可调调幅波

参阅此&#xff0c; 使用VC输出调幅波的数值和波形_c如何显示下位机传输过来的频谱信号 csdn_bcbobo21cn的博客-CSDN博客 用winform做一下&#xff1b; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Dra…

【计算机网络】HTTP协议详解(举例解释,超级详细)

文章目录 一、HTTP协议简单介绍 1、1 什么是HTTP协议 1、2 再次理解“协议” 二、HTTP请求 2、1 HTTP的工作过程 2、1、1 demo代码 2、2 URL 介绍 2、2、1 urlencode 和 urldecode 2、3 HTTP 请求格式 三、HTTP响应 3、1 响应demo 3、2 HTTP 响应格式 四、HTTP 请求和响应中的…

openwrt (一):特殊的WiFi驱动移植方法

openwrt的去驱动移植灵活多样&#xff0c;总体来说只要掌握了官方提供的操作方法即可可简单上手&#xff0c;但是也有一些稍微比较特殊的操作。比如说backport模块。 由于需要兼容很多不同版本的Linux驱动&#xff0c;很多时候需要用到backport。因此&#xff0c;如果已有的项目…