文件操作:
            标准IO         文件IO 
1.打开文件  FILE *fp       int fd
2.读写文件  fgetc/fputc    read/write 
            fgets/fputs 
            fread/fwrite 
            
3.关闭文件  fclose        close 

目录也是文件:
类似标准IO 


目录文件 ----> 目录流指针 ----> 提供给相关函数操作 


目录文件 -----> 流 (目录流指针)
  
  
  
               //FILE //struct _IO_FILE 
FILE *fp  ----->[缓存|fd]
                    |
【用户】            |
----------------------------------------- 
【内核】            |
                    V
                   fd --->[0] ---> 文件的状态 / 偏移量 
                          [1]      [                  ] ------------------> [硬盘 ]--hello.c 
                          [2]
                          ....
  
------------------------------------------------------------


01-打开目录 -- opendir
02-读目录   -- readdir
03-关闭目录 -- closedir 


 inode --- index node  

文件属性,目录  inode,name   ls 123
1.打开目标目录 
2.读取目录  
3.关闭目录 
目录 当文件看,只不过操作函数和操作文件函数不一样。

1.opendir
DIR *opendir(const char *name);
功能:
    打开一个目录获得一个目录流指针
参数:
    name:目录名
返回值:
    成功 返回目录流指针
    失败 返回NULL

#include <stdio.h>
#include <dirent.h>

int main(int argc, const char *argv[])
{

	DIR *dir = opendir(argv[1]);

	if (dir == NULL)
	{
		perror("opendir fail");
		return -1;
	}
	
	printf("success\n");
	return 0;
}

2.readdir
struct dirent *readdir(DIR *dirp);
功能:
    从目录流中读取文件信息并将保存信息的结构体
    地址返回
参数:
    dirp:目录流指针
返回值:
    包含文件信息的结构体
    出错或者读到目录流末尾返回 NULL


On Linux, the dirent structure is defined as follows:

       struct dirent {
           ino_t          d_ino;       /* inode number * 索引节点号/
           off_t          d_off;       /* offset to the next dirent */
           unsigned short d_reclen;    /* length of this record */
           unsigned char  d_type;      /* type of file;
                                           not supported
                                          by all file system types */
           char           d_name[256]; /* filename */
       };
       
       

index node --- 索引节点 


       

练习: ls -i 
 . 
 .. 
    读取目录下的所有文件,打印起inode编号 和名字

     
    

#include <stdio.h>
#include <dirent.h>

int main(int argc, const char *argv[])
{

	DIR *dir = opendir(argv[1]);

	if (dir == NULL)
	{
		perror("opendir fail");
		return -1;
	}
	
	printf("success\n");

	while (1)
	{
		struct dirent *pdir = readdir(dir);

		if (pdir == NULL)
			break;
		printf("Inode = %ld\n",pdir->d_ino);
		printf("type  = %d\n",pdir->d_type);
		printf("name  = %s\n",pdir->d_name);
	}

	closedir(dir);
	//closedir(dir);

	return 0;
}


    
练习:
       打印 指定目录下的所有文件的文件名 
    不包括 .  
           ..
    

#include <stdio.h>
#include <dirent.h>

int main(int argc, const char *argv[])
{
	if (argc != 2)
	{
		printf("Usage: %s <dirname>\n",argv[0]);
		return -1;
	}

	DIR *dir = opendir(argv[1]);

	if (dir == NULL)
	{
		perror("opendir fail");
		return -1;
	}
	
	struct dirent *pdir = NULL;
	while (pdir = readdir(dir)) 
	{
		if (pdir->d_name[0] != '.') //".vimrc"
		printf("%s ",pdir->d_name);
	}
	putchar('\n');
	closedir(dir);
	//closedir(dir);

	return 0;
} 


3、关闭目录 
 int closedir(DIR *dirp);
 功能:关闭之前已经打开的目录流对象
 参数:
       opendir的返回结果中目录流对象
 
 返回值:
        成功  0
         失败   -1;

        
练习: 
    打开一个目录 
    统计该目录下的普通文件的个数
    及 
    目录文件个数
    
    
    普通 
    DT_REG
    DT_DIR 
    
       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".//软链接 ---相当于是windows的快捷方式 

       DT_REG      This is a regular file.//普通文件 

       DT_SOCK     This is a UNIX domain socket. //socket --- 套接字文件 

       DT_UNKNOWN  The file type is unknown.  //

目录:

cd 
mkdir 
rmdir 


3.chdir
chdir ("/home/linux"); "../../"
fopen("1.mp4")
int chdir(const char *path);// /home/linux
功能:
    改变当前程序的工作路径
参数:
    path:改变到的路径
返回值:
    成功返回0
    失败返回-1


/home/linux/Desktop/Music
"file.txt"

chdir("/root");
"file.txt"

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	char buf[100];
	getcwd(buf,sizeof(buf));
	printf("buf = %s\n",buf);

	if (chdir("/home/linux")  < 0)
	{
		perror("chdir fail");
		return -1;
	}
	
	getcwd(buf,sizeof(buf));
	printf("buf = %s\n",buf);
	return 0;
}

4.getcwd //pwd 
char *getcwd(char *buf, size_t size);
功能:
    获得当前的工作路径
参数:
    buf:保存工作路径空间的首地址
    size:保存路径空间的长度
返回值:
    成功返回包含路径空间的字符串首地址
    失败返回NULL

5.mkdir 
int a  =200;
int mkdir(const char *pathname, mode_t mode);//777  666 --x--x--x
功能:
    创建一个目录
    666-
参数:
    pathname:路径
    mode:
        mode & ~umask  0002
        
返回值:
    成功返回0
    失败返回-1
    

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

int main(int argc, const char *argv[])
{
	if (mkdir(argv[1],0666) < 0)
	{
		perror("mkdir fail");
		return -1;
	}
	
	return 0;
}


6.rmdir   rm -fr    rmdir
int rmdir(const char *pathname);
功能:
    删除一个空目录文件
参数:
    pathname:目录文件的名字
返回值:
    成功返回0
    失败返回-1
        
//目录操作:
1.opendir 
2.readdir 
3.closedir 
--------
4.chdir 
5.getcwd 
6.mkdir 
7.rmdir 

8.ls (stat/fstat/lstat)

【问题】
 实现ls的功能? 
 实现ls -l
 
 
drwxrwxr-x 2 linux linux 4096 Mar 22 19:31 ./
说明:
 
    d     rwx rwx r-x     2         linux  linux  4096       Mar 22 19:31      ./
文件类型  相关权限    目录          所有者 所在组 文件大小  最后被修改的时间  文件名
          用户        (子目录个数)
          所在组      文件
          其他人      (硬链接数)
          (用户组)


          
---------------------------
硬链接:
      同一个文件,多个名字。
软链接:
      某一个文件的快捷方式。
---------------------------
ls ll
文件属性的获取
 struct stat st;
 struct stat*st;
 
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>

       int  stat(const char *path, struct stat *buf);
       int fstat(int           fd, struct stat *buf);
       int lstat(const char *path, struct stat *buf);  
           //软链接 --- lstat  获取软链接这个链接文件本身的属性信息,而不是连接到的目标文件的属性信息。
    

eg:
struct stat buf;
stat("1.txt",&buf);


练习: 模仿 stat 命令 
 File: `a.c'
  Size: 428           Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d    Inode: 946751      Links: 1
Access: (0666/-rw-rw-rw-)  Uid: ( 1000/   linux)   Gid: ( 1000/   linux)
Access: 2021-12-15 19:33:05.788944240 -0800
Modify: 2021-12-15 19:33:05.788944240 -0800
Change: 2021-12-15 19:33:05.788944240 -0800
 Birth: -


 File: 1.txt
  Size: 440           Blocks: 8          IO Block: 4096   regular file
Device: 803h/2051d    Inode: 1177788     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/   linux)   Gid: ( 1000/   linux)
Access: 2022-08-11 17:42:14.252470019 +0800
Modify: 2022-08-11 17:07:59.280573531 +0800
Change: 2022-08-11 17:08:49.828570985 +0800
 Birth: -


1.stat
int  stat(const  char  *path, struct stat *buf);
功能:
    获得文件的属性
参数:
    path: 文件的路径
    buf:  属性存放空间的首地址
返回值:
    成功返回0
    失败返回-1
       
       
       All of these system calls return a stat structure, which contains the following fields:

           struct stat {
               dev_t     st_dev;     /* ID of device containing file */ unsigned long int 
               ino_t     st_ino;     /* inode number */(*)   unsigned long int              
               mode_t    st_mode;    /* protection */(* 权限信息) unsigned int 
               nlink_t   st_nlink;   /* number of hard links */(* 硬链接数)unsigned int
               uid_t     st_uid;     /* user ID of owner */ (*UID 用户id)unsigned int
               gid_t     st_gid;     /* group ID of owner */(*group 所在组ID)unsigned int
               dev_t     st_rdev;    /* device ID (if special file) */unsigned long long int
               off_t     st_size;    /* total size, in bytes */(*文件的大小)// long unsigned int
               blksize_t st_blksize; /* blocksize for file system I/O */  long int 
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */long int
               time_t    st_atime;   /* time of last access */       (*最后访问的时间)long unsigned int
               time_t    st_mtime;   /* time of last modification */ (*最后修改的时间)
               time_t    st_ctime;   /* time of last status change */(*最后的状态改变的时间)
           };

st_mode  --- 32位 

           1111 0000 0000 0000 
           S_IFMT     0170000   bit mask for the file type bit fields
           S_IFSOCK   0140000   socket        //s    1100
           S_IFLNK    0120000   symbolic link //l    1010
           S_IFREG    0100000   regular file  //-    1000
           S_IFBLK    0060000   block device  //b     110
           S_IFDIR    0040000   directory     //d     100 
           S_IFCHR    0020000   character device //c  010
           S_IFIFO    0010000   FIFO             //p  001
           
           S_ISUID    0004000   set UID bit
           S_ISGID    0002000   set-group-ID bit (see below)
           S_ISVTX    0001000   sticky bit (see below)
           //user 
           S_IRWXU    00700     mask for file owner permissions
           S_IRUSR    00400     owner has read permission
           S_IWUSR    00200     owner has write permission
           S_IXUSR    00100     owner has execute permission
           //group 
           S_IRWXG    00070     mask for group permissions
           S_IRGRP    00040     group has read permission
           S_IWGRP    00020     group has write permission
           S_IXGRP    00010     group has execute permission
           
           //others   //掩码 
           S_IRWXO    00007     mask for permissions for others (not in group)
           S_IROTH    00004     others have read permission
           S_IWOTH    00002     others have write permission
           S_IXOTH    00001     others have execute permission

           

           
           
                                               15            
0  0  0  0  0  0  0  0|0  0  0  0  0  0  0  0 |0  0  0  0  0  0  0  0 |0  0  0  0  0  0  0  0 
                                               @  @  @  @  *  *  *  R  W  X  R  W  X  R  W  X 
                                                                    -user--  -group-  -others-
                                              |1111 0000 |0000 0000 
   
st_mode&S_IFMT


    
-rw-rw-r-- 1 linux linux 440 8月  12 09:54 1.txt                    
 
 
 1.文件类型 及 权限   (*)
   st_mode  
   st_mode & S_IFMT  == 
   0140000 & 0170000
   0140000 --> 1100
   0170000 --> 1111 & 
               ----
               1100 
               
   if ((st_mode & S_IFMT) == S_IFSOCK ) //注意 优先级 & 低于 == 
   {
       putchar('s');
       
   }
   
           S_IFSOCK   0140000   socket        // s 
           S_IFLNK    0120000   symbolic link // l 
           S_IFREG    0100000   regular file  // -
           S_IFBLK    0060000   block device  // b 
           S_IFDIR    0040000   directory     // d 
           S_IFCHR    0020000   character device // c 
           S_IFIFO    0010000   FIFO             // p
           
    st.st_mode&S_IXOTH?putchar('x'):putchar('-');
 2.硬链接数 
   st_nlink
 3.用户名   (*)  --getpwuid()
   st_uid
 4.组名     (*)  --getgrgid()
   st_gid
 5.大小 
   st_size 
 6.最后修改的时间  (*) --ctime /localtime 
   st_mtime  //time 
             
 7.文件名 
   readdir 
   struct dirent  
 
 
 getpwuid
 
 
 
 

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐