IO目录操作,库的制作,进程

本文详细介绍了如何使用C语言进行目录操作,包括opendir(), readdir(), 和 closedir()的用法,以及如何通过lstat获取文件属性。此外,还讲解了静态库和动态库的制作过程,以及进程的基本概念、类型和状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.目录操作

1.打开目录 ---opendir()

2.读取目录 --readdir()

3.关闭目录 --closedir()

4.获取文件属性 --lstat

2.库的制作

1.静态库

2.动态库

3、进程

1.进程的组成:

2.进程的类型:

1.交互进程

2.批处理进程

3.守护进程

3.进程的状态


1.目录操作

1.打开目录 ---opendir()

#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);

参数:
    name:要打开的目录名("."表示当前目录)
    
返回值:成功返回目录流指针,失败返回NULL

2.读取目录 --readdir()

readdir一次只能随机读取1个目录项(文件)

隐藏文件也读出

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

参数:目录流指针

返回值:成功返回结构体指针,失败返回NULL
    
struct dirent {
ino_t             d_ino;    /* Inode number */
off_t          d_off;       /* Not an offset; see below */
unsigned short d_reclen;    /* Len gth of this record */
unsigned char  d_type;      /* Type of file; not supported by all filesystem types */
char           d_name[256]; /* Null-terminated filename */
           };


实现ls的功能

/*===============================================
*   文件名称:ls.c
*   创 建 者:     
*   创建日期:2022年08月06日
*   描    述:
================================================*/
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{ 
    struct dirent *dir;
    DIR *dp=opendir(".");
    if(dp==NULL)
    {
        perror(opendir);
        return -1;
    }

    while((dir=readdir(dp))!=NULL)
    {
        if(dir->d_name[0]!='.')
        {
            //printf("%s\n",dir->d_name);
            //write(1,dir->d_name,strlen(dir->d_name));
            fputs(dir->d_name,stdout);
            printf("    ");
        }
    }
    printf("\n--------------------------\n");
    closedir(dp);
    return 0;
} 

 

 

3.关闭目录 --closedir()

#include <sys/types.h>
#include <dirent.h>

int closedir(DIR *dirp);
参数:
    dirp:要关闭的目录流指针
    
返回值:成功返回0,失败返回-1

4.获取文件属性 --lstat

lstat可以获取链接文件的信息,stat只能查取本身文件的信息。fsts,通过文件描述符访问文件信息,lstat通过文件名访问

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

int stat(const char *pathname, struct stat *statbuf);

int fstat(int fd, struct stat *statbuf);

int lstat(const char *pathname, struct stat *statbuf);

参数:pathname:文件名
    statbuf:
    
一级指针,传同类型变量的地址(类似返回值)

返回值:成功返回0,失败返回-1

struct stat {
               dev_t     st_dev;         /* ID of device containing file */
               ino_t     st_ino;         /* Inode number */
               mode_t    st_mode;        /* File type and mode */
               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;     /* Block size for filesystem I/O */
               blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

               /* Since Linux 2.6, the kernel supports nanosecond
                  precision for the following timestamp fields.
                  For the details before Linux 2.6, see NOTES. */

               struct timespec st_atim;  /* Time of last access */
               struct timespec st_mtim;  /* Time of last modification */
               struct timespec st_ctim;  /* Time of last status change */

           #define st_atime st_atim.tv_sec      /* Backward compatibility */
           #define st_mtime st_mtim.tv_sec    //最后一次修改的秒数
           #define st_ctime st_ctim.tv_sec
           };

实现ls -l
    
    
    
    
    
    打印时,不知道数据类型,在编译时一个一个调试
    
       #include <sys/types.h>
       #include <grp.h>
       #include <sys/types.h>
       #include <pwd.h>

    
    getgrgid    --得到用户组名的函数
    getpwuid    --得到用户名的函数
    localtime    --时间的格式
    
    mode_t    st_mode
    
   查找inode(7)
    获取文件类型:
           S_IFMT     0170000   bit mask for the file type bit field

           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
    
 如果st_mode &  S_IFMT 等于对应文件类型宏,则文件类型宏对应类型就位文件类型
               
         
    查找文件权限
         st_mode &    对应权限宏 ==宏本身    表示具有该权限      
               
 
        S_IRUSR     00400   owner has read permission
        S_IWUSR     00200   owner has write permission
        S_IXUSR     00100   owner has execute permission
               
               
        S_IRGRP     00040   group has read permission
        S_IWGRP     00020   group has write permission
        S_IXGRP     00010   group has execute permission

               
        S_IROTH     00004   others have read permission
        S_IWOTH     00002   others have write permission
        S_IXOTH     00001   others have execute permission
               
        九个权限,
                100 000 000
                010 000 000
                   001 000 000
               ......
               利用1,左移,先打印左移九位的,最后打印左移1位的

2.库的制作

库的本质: 二进制文件

库的类型: 静态库和动态库(共享库)

静态库与动态库的区别在于加载程序的时机不同,编译,运行

库文件一般在/lib /usr/lib

1.静态库

在程序编译阶段(链接阶段),将库中的代码,以复制拷贝的方式加载到源程序中。静态库一般不放入默认文件夹,用-L指明路径

特点:

1.运行时,不需要静态库存在

2.方便移植,可移植性强

3.占资源空间,编译之后可执行文件大

4.优化升级麻烦,需要重新编译源文件

静态库制作流程:

        1.先预留接口函数

        2.实现所有函数功能

        3.生成所有的.c文件的目标文件(以.o结尾的文件)

        gcc -c hello.c -o hello.o

        4.编译生成静态库。(ar crs 生成静态库)

        ar crs libhello.a hello.o

功能函数,头文件,主程序(头文件用"")(1.2)

gcc -c hello.c -o hello.o (3)

ar crs libhello.a hello.o(4)

ar crs 库文件名 *.o 多个.o时

静态库文件的命名规范:

以lib开头,以.a结尾,中间为库名

链接时,链接的是库名

libhello.a --->库文件名

hello --->库名

链接静态库 gcc main.c -lhello (默认去/lib /usr/lib下找)

链接静态库 gcc main.c -L. -lhello (去-L之后的路径找)

 

2.动态库

在程序编译阶段(),只是将需要用到的函数做一个记录(函数名),最后在程序运行阶段再加载函数代码。动态库一般放入默认文件夹。

特点:       

         1.运行时,需要动态库存在

        2.可移植性差

        3.不占资源空间,编译之后可执行文件小

        4.优化升级方便,不需要重新编译源文件

动态库的制作流程:

1.先预留接口函数

2.实现所有函数功能

3.将所有的.c文件生成对应的目标文件

gcc -c -fPIC hello.c -o hello.o

-fPIC表示生产位置无关代码

4.编译生成动态库

gcc -shared -o libhello.so hello.o

动态库文件的命名规范:

以lib开头,以.so结尾,中间为库名

libhello.so --->库文件名

hello --->库名

链接动态库

1.把动态库复制到/lib或/usr/lib下

gcc main.c -lhello (默认去/lib /usr/lib下找)

2.在LD_LIBRARY_PATH 环境变量中加上库所在路径 (临时,只对当前shell有效)

3.添加 /etc/ld.so.conf.d/my.conf文件,把库所在的路径添加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见

​​​​​​

 

 

 

3、进程

程序:静态的,是有序数据指令的集合

进程:正在执行的程序

系统分配资源的最小单位,总称。进程是程序执行的一次完整过程(创建、调用、执行、消亡)

程序的组成:

正文段,用户数据段

1.进程的组成:

PCB:

进程ID:

用户名、用户组名

进程的状态,优先级

文件描述符表

pc(程序寄存器):

记录程序下一条指令的地址

保存现场情况,以便继续运行

堆栈(栈):

2.进程的类型:

1.交互进程

与终端相关(终端关了,进程无法运行),可以在前台运行,也可以在后台运行

可执行文件 &(后台程序运行)

kill -9 pid号 结束进程

2.批处理进程

与终端无关,可以将指定的进程放在一个工作队列中按顺序执行,一般由系统管理员操作

3.守护进程

与终端无关,在后台一直循环执行任务

3.进程的状态

+前台进程 > < 优先级

R --运行态(就绪态):正在运行或者准备运行的进程

等待态:两种等待态,区别在于是否能被信号打断。

S --(sleep)睡眠态/可中断等待态:等待某种资源,资源来了继续执行

D --(deep sleep)不可中断等待态

T --暂停态:暂停运行,知道有信号唤醒为止

Z --僵尸态:进程结束之后没有进行资源回收,该进程状态变成僵尸态,占资源,不回应

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值