小萌新的IO进线程——文件IO

目录

文件IO

1、概念

2、文件描述符

文件IO相关系统调用函数

1、打开或者新建文件 —— open

2、关闭文件 —— close

3、读文件 —— read

4、写文件 —— write 

5、文件定位 —— lseek 

目录操作

1、打开目录 —— opendir

2、关闭目录 —— closedir

3、读取目录项 —— readdir

4、文件属性获取 —— stat、fstat、lstat


文件IO

1、概念

遵循POSIX标准,文件IO是通过系统调用函数直接操作文件

2、文件描述符

在文件IO中,一个文件对应了一个文件描述符。cx在此

本质:文件描述符是一个由系统自动分配的最小的非负整数,当用户创建或者打开一个文件时,系统会向当前进程返回一个文件描述符。

文件IO相关系统调用函数

1、打开或者新建文件 —— open

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

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

参数
        pathname:文件名(包含路径)
        flags:打开方式
            O_RDONLY:以只读方式打开文件,文件必须存在
            O_WRONLY:以只写方式打开文件
            O_RDWR:以读写方式打开文件

***************************前三个选项中必须选择一个进行填写************************************

            O_CREAT:如果文件不存在,则新建该文件
            O_EXCL:通常和O_CREAT结合使用,用于判断文件是否存在
            O_TRUNC: 打开文件时,先清空文件内容
            O_APPEND:以追加的方式打开文件,所有对文件的写操作默认在文件末尾进行

   mode:当用户需要创建新文件时,使用O_CREAT选项创建,并使用该参数给新文件赋初始权限

//默认0664

返回值:
         成功返回文件描述符,失败返回-1

  umask:文件权限掩码
     最终文件权限 == 初始权限 & (~umask)

eg

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{ 
    int fd = open("1.txt",O_RDONLY);
    if(fd < 0)
    {
        perror("open 1.txt");
        exit(-1);
    }
    printf("成功打开文件fd = %d\n",fd);

    return 0;
} 

ie

 

2、关闭文件 —— close

#include <unistd.h>

int close(int fd);


    参数:
        fd:文件描述符

eg

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{ 
    int fd = open("1.txt",O_RDONLY);    //打开文件
    if(fd < 0)
    {
        perror("open 1.txt");
        exit(-1);
    }
    printf("成功打开文件fd = %d\n",fd);
    close(fd);                            //关闭文件
    return 0;
} 

ie

3、读文件 —— read

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);


    参数:
        fd:文件描述符
        buf:存储读取内容的首地址
        count:请求读取的字节数


    返回值:
        (1)成功返回读取的字节数,(2)失败返回-1,(3)0表示读到文件末尾

eg

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{ 
    int fd = open("1.txt",O_RDONLY);
    if(fd < 0)
    {
        perror("open 1.txt");
        exit(-1);
    }
    char arr[32] = {0};
    int ret = read(fd, arr, 17);
    if(ret < 0)
    {
        perror("read");
        exit(-1);
    }
    printf("ret=%d arr=%s\n",ret,arr);
    
    close(fd);
    return 0;
} 

ie

4、写文件 —— write 

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);


    参数:
        fd:文件描述符
        buf:存储写入内容的首地址
        count:请求写入的字节数


    返回值:
        成功返回写入的字节数,失败返回-1  

eg

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{ 
    int fd = open("1.txt",O_WRONLY);
    if(fd < 0)
    {
        perror("open 1.txt");
        exit(-1);
    }
    char arr[64] = {0};
    fgets(arr,64,stdin);
    int ret = write(fd,arr,strlen(arr));
    if(ret < 0)
    {
        perror("write");
        exit(-1);
    }
    close(fd);
    return 0;
} 

ie

5、文件定位 —— lseek 

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

off_t lseek(int fd, off_t offset, int whence);

       

         参数:

                fd:文件描述符
                offset:偏移量,可正可负,正表示向后偏移,负表达向前偏移
                whence:基准点
                    SEEK_SET:文件开头
                    SEEK_CUR:文件指针当前位置
                    SEEK_END:文件末尾

        返回值:
                成功返回文件指针当前位置相对于文件开头的偏移量,失败返回-1

eg

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{ 
    int fd = open("1.txt",O_WRONLY);
    if(fd < 0)
    {
        perror("open 1.txt");
        exit(-1);
    }
    
    lseek(fd,0,SEEK_END);

    char arr[64] = {0};
    fgets(arr,64,stdin);
    int ret = write(fd,arr,strlen(arr));
    if(ret < 0)
    {
        perror("write");
        exit(-1);
    }
    close(fd);
    return 0;
} 

ie

目录操作

1、打开目录 —— opendir

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

DIR *opendir(const char *name);


   参数:
           name:目录名


   返回值:
           成功返回目录流指针,失败返回NULL;

eg

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

int main(int argc, char *argv[])
{ 
    //打开目录
    DIR *dir = opendir(".");
    if(NULL == dir)
    {
        perror("opendir");
        exit(-1);
    }
    printf("打开成功\n");

    //colsedir(dir);
    return 0;
}

ie

 

2、关闭目录 —— closedir

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

int closedir(DIR *dirp);


    参数:
           dirp:目录流指针

eg

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

int main(int argc, char *argv[])
{ 
    //打开目录
    DIR *dir = opendir(".");
    if(NULL == dir)
    {
        perror("opendir");
        exit(-1);
    }
    printf("打开成功\n");

    //关闭目录
    closedir(dir);
    return 0;
} 

ie

 

3、读取目录项 —— readdir

#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;    /* Length of this record */
    unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
    char           d_name[256]; /* Null-terminated filename */
};

eg

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

int main(int argc, char *argv[])
{ 
    //打开目录
    DIR *dir = opendir(".");
    if(NULL == dir)
    {
        perror("opendir");
        exit(-1);
    }

    //读取目录项
    struct dirent *dt = NULL;
    while(NULL != (dt = readdir(dir)))
    {
        if(dt->d_name[0] != '.')//不打印隐藏文件
        printf("%s ",dt->d_name);
    }
    putchar('\n');

    //关闭目录
    closedir(dir);
    return 0;
} 

 ie

4、文件属性获取 —— stat、fstat、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 */
               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
}


文件类型:
        eg:
            st_mode & S_IFMT == S_IFREG //表示该文件为普通文件        
    
           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

文件权限:
          eg:
               if(st_mode & S_IRUSR)   //如果结果为真,表示具有该权限
               {
                   pritnf("r");
               }
               else
               {
                   printf("-");
               }

           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
           

  通过用户ID得到用户名:
       #include <sys/types.h>
       #include <grp.h>
               
       struct group *getgrgid(gid_t gid);       
               
  通过用户组ID得到用户组名:             
         #include <sys/types.h>
       #include <pwd.h>

       struct passwd *getpwuid(uid_t uid);

eg

#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>

int main(int argc, char *argv[])
{
    char *arr[64] = {0};
    char *tmp = NULL;
    int len =0;
    int i = 0;
    int j = 0;
    int a = 0;

    //1、打开目录
    DIR *dp = opendir(".");
    if(NULL == dp)
    {
        perror("opendir");
        return -1;
    }

    //2、列出所以目录名
    struct dirent *dt = NULL;
    while((dt = readdir(dp)) != NULL)
    {
    //3、不显示隐藏文件
        if(dt->d_name[0] !='.')
        {
        arr[a] = dt->d_name;
        len ++;
        a++;
        }    
    }

    //4、排序

    for(i = 0; i < len-1; i++)
    {
        for(j = 0; j < (len-1)-i; j++)
        if(strcmp(arr[i],arr[i+1]) > 0)
        {
            tmp = arr[i];
            arr[i] = arr[i+1];
            arr[i+1] = tmp;
        }
    }

    //5、列出详细信息
    struct stat info;
    struct tm*myt = NULL;
    //6、所以的民字都赋给结构体
   for (i = 0; i < len; i++ )
    {
    lstat(arr[i],&info);
    
    //7、时间
    myt = localtime(&info.st_mtime);
    
    switch(info.st_mode & S_IFMT)
    {
        case S_IFREG:
            printf("-"); break;
        case S_IFLNK:
            printf("l"); break;
        case S_IFSOCK:
            printf("s"); break;
        case S_IFIFO:
            printf("p"); break;
        case S_IFBLK:
            printf("b"); break;   
        case S_IFCHR:
            printf("c"); break;
        case S_IFDIR:
            printf("d"); break;
    }
    char arr1[4] = {'x','w','r','-'};
    for(j = 8; j>=0; j--)
    {
      if(info.st_mode & (S_IXOTH << j))
      {
          printf("%c",arr1[j%3]);
      }
      else
      {
          printf("%c",arr1[3]);
      }
    }
    struct group *gid = NULL;
    struct passwd *uid = NULL;
    gid = getgrgid(info.st_gid);
    uid = getpwuid(info.st_uid);
    printf("%s %s",gid->gr_name,uid->pw_name);
    //、打印
    printf("%ld %ld %d月 %d %02d:%02d %s\n",info.st_nlink, info.st_size, myt->tm_mon+1, myt->tm_mday, myt->tm_hour, myt->tm_min, arr[i]);
    }
    //、关闭目录
    closedir(dp);
    return 0;
} 

ie

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值