系统IO笔记

系统IO
函数概述:

1. open  close
2. write  read		size_t write(int fd,const void *buf,size_t count)
3. lseek(int fd,long offset,int origin)
4.dup	dup2,	int 	dup(int fd)	int dup2(fd1,fd2)
5.time	asctime, ctime, localtime,strltime,
6. int fileno(FILE *fp)		FILE *fdopen(int fd) 
7. stat	
  1. open close
    int __cdecl open(const char *_Filename,int _OpenFlag,…) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    以指定的方式打开文件,若成功,返回一个新的文件的描述符,失败返回-1

    文件描述符:每打开一个文件,就会用一个未被使用的最小的文件描述符来记录
    文件描述符实际上就是数组的下标,范围从0开始到1023截止,一旦拿到文件描述符,就可以对相应的文件进行操作

    参数1 要打开的文件的路径
    参数2 如下系统io的6种打开方式
    O_RDONLY 0
    O_WRONLY 1
    O_RDWR 2
    以上宏值是互斥的,一次可以使用一个,但可以或上其他的值
    //标准IO:fopen,6种打开方式,/系统IO
    r O_RDONLY; 只读
    r+ O_RDWR 可读可写
    w O_WRONLY|O_CREAT|O_TRUNC,0666
    w+ O_RDWR|O_CREAT|O_TRUNC,0666
    a O_WRONLY|O_CREAT|O_APPEND,0666
    a+ O_WDWR|O_CREAT|O_APPEND,0666
    //文件IO:

int open(const char* pathname,int flags)
O_RDONLY 只读
O_RDWR 可读可写
O_WRONLY 只写
O_CREATE 若文件不存在创建,并用第三个参数为其设置权限
O_TRUNC,0XXX 若文件已经存在,清零
O_APPEND 追加,在文件的末尾进行写操作
返回值:成功返回文件描述符
失败返回1并设置errno
2.close
int close(int fildes)

3.read
ssize_t read(int fd,void *buf,size_t count)
int fd ,open的返回值,buf缓冲区接收数据,count 读取的最大字节数

4.write
ssize_t write(int fd,const char* buf,size_f count)

  1. write read size_t write(int fd,const void *buf,size_t count)
    3.read
    ssize_t read(int fd,void *buf,size_t count)
    int fd ,open的返回值,buf缓冲区接收数据,count 读取的最大字节数

4.write
ssize_t write(int fd,const char* buf,size_f count)

  1. lseek(int fd,long offset,int origin)
    off_t lseek(int fd,long _Offset,int whence)
    offset:相对基准点whence的偏移量。一字节为单位,正数表示向前移动(往文件结尾方向偏移),负数表示向后移动
    whence :当前位置的基点 1. SEEK_SET 文件的起始位置
    2.SEEK_CUR 文件当前读取位置
    3.SEEK_END 文件的结束位置
    return value:成功返回文件当前读取的位置
    失败返回文件结束位置

4文件描述符重定向.dup dup2
文件描述符重定向:
int dup(int oldfd);//复制文件描述符,作用就是让一个文件拥有多个文件描述符,失败返回-1

 语法:
    int fd2;
    
    fd2 = dup(fd1);//让fd2也来记录fd1保存的文件
 
 
 注意:dup不是原子操作,不建议使用
    原子操作:不可分割的操作方式,用来解决多进程多线程竞争
 
 
 
 int dup2(int oldfd, int newfd);//文件描述符重定向
 //成功,将新文件描述符返回出去,如果失败,返回-1
    如果newfd已经记录了一个文件,此时关闭newfd记录的文件,重定向到oldfd记录的文件
 
 
 将参数二的fd2去保存参数一fd1记录的文件
  1. int fileno(FILE *fp) FILE *fdopen(int fd)
    6…time asctime, ctime, localtime,strltime,
#include <stdio.h>
#include <time.h>
        /*
        时间函数相关的结构体
         struct tm {
               int tm_sec;          seconds 
               int tm_min;          minutes 
               int tm_hour;         hours 
               int tm_mday;         day of the month 
               int tm_mon;          month 
               int tm_year;         year 
               int tm_wday;         day of the week 
               int tm_yday;         day in the year 
               int tm_isdst;        daylight saving time 
           };
               The members of the tm structure are:
        */

int main()
{
    struct tm *tm1,*p;
    char *tm2;
    long t;
    while (1)
    {
        t = time(NULL);//获取当前时间
        printf("%ld\n",t);
        sleep(1);
        char *ret;
        ret = ctime(&t);//依当前时间t获取一段关于时间的字符串:如下eg
        printf("%s\n",ret);//eg:Fri Sep 20 16:22:14 2019
        

        tm1 = localtime(&t);
        //依当前时间t获取时间数据到时间结构体tm1中
        //时间结构体tm见文件开头
        printf("111year == %d  month == %d  day == %d  hour == %d\n",tm1->tm_year+1900,tm1->tm_mon+1,tm1->tm_mday,tm1->tm_hour);
        tm2 = asctime(tm1);//获取依当前时间t得到的时间结构体数据\
        然后将其转换成字符串函数返回其字符串存储的地址、、\
        然后就可以直接打印其字符串得到时间数据
        printf("%s\n",tm2);

        char buf[100];
        strftime(buf,100,"%y %m %d %S\n\0",tm1);
        //size_t strftime(char *s, size_t max,        \
        const char *format, const struct tm *tm);
        //将时间结构体tm1格式化输出到字符串数组中
        printf("%s",buf);
    }
    return 0;
    
}
  1. stat
    获取用户组信息
    1.获取文件或目录的属性:
    int stat(const char *path, struct stat *buf);
    //EG stat(argv[1],&st)
    //将文件信息存储到参数结构体buf中
    int fstat(int fd, struct stat *buf);
    int lstat(const char *path, struct stat *buf)
    三个函数区别:
    stat函数返回一个与此命名文件有关的信息结构
    fstat函数获得已在描述符filedes上打开的文件的有关信息
    lstat函数类似于stat,但是当命名的文件是一个符号连接时,
    lstat返回该符号连接的有关信息,而不是由该符号连接引用的文件的信息

结构体
//struct stat {
// dev_t st_dev; /* ID of device containing file 文件id号*/
// 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 file system 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(最后一次修改的(依属性) /
//};
/

ls -l

st_mode        st_nlink   st_uid st_gid    st_size  st_mtime 

文件类型 文件权限 硬链接数 用户 用户组名 文件大小 最后一次修改时间 文件名

1 . stat (路径,文件结构体地址) 成功返回0,失败返回-1并设置errno

2 .
获取用户信息
struct passwd *getpwuid(uid_t uid)
参数需要一个用户信息,返回一个用户信息结构体

struct passwd *getpwnam(const char *name)
参数需要一个用户信息,返回一个用户信息结构体

8、从stat下得文件属性的宏
The following flags are defined for the st_mode field:

       S_IFMT     0170000   bit mask for the file type bit fields
       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
       S_ISUID    0004000   set UID bit
       S_ISGID    0002000   set-group-ID bit (see below)
       S_ISVTX    0001000   sticky bit (see below)
       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
       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
       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

使用例子

char *file_mode(mode_t m)
{
    char *buf;
    buf = malloc(10);
    {
    if (buf == NULL)
    {
        perror("malloc");
        exit(1);
    }
    }

    buf[0] = m & S_IRUSR ? 'r':'-';
    buf[1] = m & S_IWUSR ? 'w':'-';
    buf[2] = m & S_IXUSR ? 'x':'-';

    buf[3] = m & S_IRGRP ? 'r':'-';
    buf[4] = m & S_IWGRP ? 'w':'-';
    buf[5] = m & S_IXGRP ? 'x':'-';

    buf[6] = m & S_IROTH ? 'r':'-';
    buf[7] = m & S_IWOTH ? 'w':'-';
    buf[8] = m & S_IXOTH ? 'x':'-';

    buf[9] = '\0';

    return buf;
}
}
char file_type(mode_t m)
{
    if(S_ISREG(m))//判断是否是普通文件
    return '-';
    if(S_ISDIR(m))
    return 'd';
    if(S_ISCHR(m))
    return 'c';
    if(S_ISBLK(m))
    return 'b';
    if(S_ISFIFO(m))
    return 'p';
    if(S_ISLNK(m))
    return 'l';
    if(S_ISSOCK(m))
    return 's';
}

9、目录函数等
9.1. opendir
DIR *opendir(const char *name);
//打开一个目录,如果成功,返回一个目录指针,失败返回NULL,设置errno的值
9.2.closedir
9.3.readdir
struct dirent *readdir(DIR *dirp);
//读取目录,成功,返回一个目录文件结构体指针,失败返回NULL,设置errno的值
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 */
   };

9.4. getopt
#include <unistd.h>
int getopt(int argc, char * const argv[],const char *optstring);
//参数一:主函数的argc,参数二:主函数的argv,参数三:命令行选项

//返回值:如果找到命令行选项,返回该字符,如果没有找到,返回,分析结束,返回-1

注意:使用命令行选项,需要加上-,而且是在选项之前,例如: ls -lai

eg:
void main (int argc,char *argv[])
{
    int ret;
    while(1)
    {
        ret = getopt(argc,argv,argv[1]);
        if(ret == -1){
            perror("getopt");
            return;
        }
        switch (ret)
        {
        case 1:
            perror("ret");
            break;
        case: 'l':
            printf("%c\n",ret);
            break;
        case 'a':
            printf("%c\n",ret);
            break;        
        case 'i':
            printf("%c\n",ret);
            break;          
        default:
            break;
        }
    }
}

9.5. glob
int glob(const char *pattern, int flags,int (*errfunc) (const char *epath, int eerrno),glob_t *pglob);

//参数一:路径 参数二:0 参数三:NULL 参数4: glob_t结构体
eg:

#include <stdio.h>
#include <glob.h>
void main (int argc,char *argv[])
{
    glob_t glb;
    glob("./*",0,NULL,&glb);
    int i;
    printf("%s\n",*glb.gl_pathv);
    printf("%d\n",glb.gl_pathc);
    for ( i = 0; i < glb.gl_pathc; i++)
    {
        printf("%s\n",glb.gl_pathv[i]);
    }
}
 

编写在ubuntu中实现类shell指令的程序
现象:
1.实现查看文件属性实现查看文件属性

2.MYls -l实现查看文件夹文件
查看文件夹即文件夹内的文件属性

3.ls -a //ls -l程序删除一部分,只打印名字
在这里插入图片描述
4.ls -i //寻找inode号
在这里插入图片描述
5.ls -n //ls -l里面不用获取用户名和用户组名
在这里插入图片描述
6.ls -lian //getopt
在这里插入图片描述
code

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


int  select_opt(int argc,char* const * argv,char *argv1);
char file_type(mode_t m)
{
    if(S_ISREG(m))
	return '-';
    if(S_ISDIR(m))
	return 'd';
    if(S_ISCHR(m))
	return 'c';
    if(S_ISBLK(m))
	return 'b';
    if(S_ISFIFO(m))
	return 'p';
    if(S_ISLNK(m))
	return 'l';
    if(S_ISSOCK(m))
	return 's';
}

char *file_mode(mode_t m)
{
    char *buf;
    buf = (char*)malloc(10);
    if (buf == NULL)
    {
        perror("malloc");
        exit(1);
    }
    buf[0] = m & S_IRUSR ? 'r':'-';
    buf[1] = m & S_IWUSR ? 'w':'-';
    buf[2] = m & S_IXUSR ? 'x':'-';

    buf[3] = m & S_IRGRP ? 'r':'-';
    buf[4] = m & S_IWGRP ? 'w':'-';
    buf[5] = m & S_IXGRP ? 'x':'-';

    buf[6] = m & S_IROTH ? 'r':'-';
    buf[7] = m & S_IWOTH ? 'w':'-';
    buf[8] = m & S_IXOTH ? 'x':'-';
    buf[9] = '\0';
    return buf;
}
void display_f(struct stat st)
{
    char mode = file_type(st.st_mode);
    printf("%c",mode);

    char *authority;
    authority = (char*)malloc(sizeof(char)*10);
    authority = file_mode(st.st_mode);
    printf("%s ",authority);

    printf("%d ",st.st_nlink);

    struct passwd *pwd;
    pwd = getpwuid(st.st_uid);
    printf("%s ",pwd->pw_name);

	struct group *grp;
	grp = getgrgid(st.st_gid);
	printf(" %s",grp->gr_name);

    printf("%ld ",st.st_size);

    struct tm *s;
    s = localtime(&st.st_atime);
    char tm1[100];
    strftime(tm1,100,"%D %T",s);
    printf("%s ",tm1);

}

void display_f1(struct stat st)
{
    char mode = file_type(st.st_mode);
    printf("%c",mode);

    char *authority;
    authority = (char*)malloc(sizeof(char)*10);
    authority = file_mode(st.st_mode);
    printf("%s ",authority);

    printf("%d ",st.st_nlink);
/*
    struct passwd *pwd;
    pwd = getpwuid(st.st_uid);
    printf("%s ",pwd->pw_name);

	struct group *grp;
	grp = getgrgid(st.st_gid);
	printf(" %s",grp->gr_name);
*/
    printf("%ld ",st.st_size);

    struct tm *s;
    s = localtime(&st.st_atime);
    char tm1[100];
    strftime(tm1,100,"%D %T",s);
    printf("%s ",tm1);

}


int main(int argc,char *argv[])
{
    glob_t glb;
    char dir_name[100];
    struct stat file_st;
    struct dirent *d;//目录信息结构体指针
    
    
    DIR *dir;
    int i = 0;
    char ch;

    int sum = 0; 
    int stat1 = stat(argv[1],&file_st);
        if (stat1<0)
    {
        perror("stat");
        return -1;
    }
    ch = file_type(file_st.st_mode);

    if(ch == 'd'){
            if(argc>2)
            sum =select_opt(argc,argv,argv[2]);
            //printf("sum  %d",sum);
            dir = opendir(argv[1]);
            if(dir == NULL)
            {
                perror("opendir");
                return -2;
            }  
            switch (sum)
            {
                case 205://-al
                    while (1)
                    {
                        d = readdir(dir);
                        if (d == NULL)  
                        {
                            perror("read");
                            break;
                        }
                        sprintf(dir_name,"%s/%s",argv[1],d->d_name);
                        if(stat(dir_name,&file_st) < 0)//获取文件属性
                        {
                        perror("stat_dir_file");
                        return -4;
                        }

                        display_f(file_st);
                        printf(" %s\n",d->d_name);//8.获取文件名
                    }
                    break;
                case 96 ://a
                    glob("./*",0,NULL,&glb);
                    for ( i = 0; i < glb.gl_pathc; i++)
                    {
                        printf("%s\n",glb.gl_pathv[i]);
                    }
                    break;
                case 107://-l
                    while (1)
                    {
                        d = readdir(dir);
                        i++;
                        if (d == NULL)  
                        {
                            perror("read");
                            break;
                        }
                        sprintf(dir_name,"%s/%s",argv[1],d->d_name);
                        if(stat(dir_name,&file_st) < 0)//获取文件属性
                        {
                        perror("stat_dir_file");
                        return -4;
                        }
                        if(i>2){
                            display_f(file_st);
                            printf(" %s\n",d->d_name);//8.获取文件名
                        }
                    }                    
                    break;
                case 109://ls -n
                    while (1)
                    {
                        d = readdir(dir);
                        if (d == NULL)  
                        {
                            perror("read");
                            break;
                        }
                        sprintf(dir_name,"%s/%s",argv[1],d->d_name);
                        if(stat(dir_name,&file_st) < 0)//获取文件属性
                        {
                        perror("stat_dir_file");
                        return -4;
                        }

                        display_f1(file_st);
                        printf(" %s\n",d->d_name);//8.获取文件名
                    }
                    break;
                case 104:// -i
                    while (1)
                    {
                        d = readdir(dir);
                        if (d == NULL)  
                        {
                            perror("read");
                            break;
                        }
                        sprintf(dir_name,"%s/%s",argv[1],d->d_name);
                        if(stat(dir_name,&file_st) < 0)//获取文件属性
                        {
                        perror("stat_dir_file");
                        return -4;
                        }

                        printf("node:%ld  ",file_st.st_ino);
                        printf(" %s\n",d->d_name);//8.获取文件名
                    }
                    break;
                case 311:
                    while (1)
                    {
                        d = readdir(dir);
                        if (d == NULL)  
                        {
                            perror("read");
                            break;
                        }
                        sprintf(dir_name,"%s/%s",argv[1],d->d_name);
                        if(stat(dir_name,&file_st) < 0)//获取文件属性
                        {
                        perror("stat_dir_file");
                        return -4;
                        }
                        printf("node:%ld  ",file_st.st_ino);
                        display_f(file_st);
                        
                        printf(" %s\n",d->d_name);//8.获取文件名
                    }
                    break;
                default:

                    break;
            }    

    }
    
    else
    {
        for(i=1;i<argc;i++)
        {

            if(stat(argv[i],&file_st) < 0)//获取文件属性
            {
            perror("stat");
            return -4;
            }

            display_f(file_st);
            printf(" %s\n",argv[i]);//8.获取文件名
        }
    }
    //display_f(file_st);

    return 0;
}




int  select_opt(int argc,char* const * argv,char *argv1)
{
    int i;
    int *ret;
    int sum = 0;
    ret = (int*)malloc(sizeof(int)*4);

    for ( i = 0; i < 4; i++)
    {
        ret[i] = getopt(argc,argv,argv1);
        if(ret[0] == -1)
        {
            perror("getopt");
            return;
        }
        switch (ret[i])
        {
        case 1:
            perror("ret");
            break;
        case 'l':
            printf("ret = %c\n",ret[i]);
            break;
        case 'a':
            printf("ret = %c\n",ret[i]);
            break;
        case 'i':
            printf("ret = %c\n",ret[i]);
            break;
        case 'n':
            printf("ret = %c\n",ret[i]);
            break;
        default:
            break;
        }       
    }
    for ( i = 0; i < 4; i++)
    {
        //printf("%d ",ret[i]);
        sum+= ret[i];
    }
    puts("");
    return sum;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值