IO进程线程,文件IO(open),文件(stat)与目录(opendir)属性的读取

      一、文件IO

1、文件io通过系统调用来操作文件

系统调用:系统提供给用户的一组API(接口函数)

        open/read/write/close/lseek...

用户空间进程访问内核的接口

把用户从底层的硬件编程中解放出来

极大的提高了系统的安全性

使用户程序具有可移植性(同一系统下)

是操作系统的一部分

文件io没有缓存区概念

文件io操作文件的方式:通过文件描述符

shell默认打开了三个文件:

标准输入  标准输出 标准错误

stdin stdout  stderr                  用流来表示

      0         1       2                   用文件描述符表示

2、文件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:如果文件不存在,则创建文件,此时用到open函数的第二种形式。

                     O_TRUNC:如果文件存在则清空文件的内容。

                     O_APPEND:以追加的方式打开文件。

                    

       mode:文件的权限,八进制(0777)

       返回值

              成功返回一个新的文件描述符,失败返回(-1)并设置错误号。

       2、close函数

       作用:

              关闭文件

       头文件

          #include <unistd.h>

       函数原型

              int close(int fd);

       参数

        想要关闭的文件描述符

       返回值

              成功返回0,失败返回(-1)并设置错误号。

       3、read/write

        1、read

              作用:

                     向文件读取内容

           头文件:

            #include <unistd.h>

              函数原型

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

              参数

                     fd:想要操作的文件描述符

                     buf:读取到的内容放到哪个地址

                     count:读取到的文件中的字符数量

              返回值:

              成功返回已经读取到的字节数,失败返回-1并设置错误号,读取到文件末尾返回0。

        2、write

              作用:

                     向文件写入内容

           头文件:

            #include <unistd.h>

              函数原型

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

              参数

                     fd:想要写入的文件描述符

                     buf:需要写入文件的内容

                     count:写入文件中字符数量

              返回值:

                     成功返回已经写入的字节数,失败返回-1并设置错误号。

       4、lseek

              作用:

                     偏移文件内的书签

           头文件:

            #include <sys/types.h>

              函数原型

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

              参数

                     fd:想要写入的文件描述符

                     offset:偏移量,正数表示后偏移,负数前偏移,0不偏移

                     whence:书签偏移的起始位置

                                   SEEK_SET:文件头

                                   SEEK_CUR:当前位置

                                   SEEK_END:文件末尾

              返回值:

                     成功返回当前偏移到的位置,失败返回-1并设置错误号。

      二、文件和目录

1、stat

       #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);

stat,lstat通过传入的pathname获取文件属性

fstat通过用open打开的文件的文件描述符获取文件属性

stat在操作软链接文件时会获取源文件的相关属性

lstat在操作软链接文件时会获取链接文件的相关属性

成功返回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

           };

1、文件类型(可以用以下的宏确定文件类型,这些宏的参数都是struct stat结构中的ts_mode成员)

S_ISREG(m)  is it a regular file?

S_ISDIR(m)  directory?

S_ISCHR(m)  character device?

S_ISBLK(m)  block device?

S_ISFIFO(m) FIFO (named pipe)?

S_ISLNK(m)  symbolic link? (Not in POSIX.1-1996.)

S_ISSOCK(m) socket? (Not in POSIX.1-1996.)

2、文件权限

       存放在st_mode低9位,从高位到低位分别表示用户权限、同组用户权限、其它用户权限,该位为1表示有权限,0表示没有权限

3、链接数

直接通过st_nlink得到

4、文件所有者

getpwuid函数相关操作得到

5、文件所属组

getgrgid函数相关操作得到

6、文件字节大小

直接通过st_size得到

7、文件更新时间

ctime(&st_ctime)得到文件的更新时间

#include <stdio.h>
#include <sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<string.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
int main(int argc, char *argv[])
{
   if(2!=argc)
    {
        printf("error\n");
    }
    struct stat st;
    lstat(argv[1],&st);
    if(S_ISREG(st.st_mode))
        printf("-");
    else if (S_ISDIR(st.st_mode))
        printf("d");
    else if(S_ISLNK(st.st_mode))
        printf("l");
    int i=8;
    for ( ; i >= 0; i-=3)
    {
        if(st.st_mode&1<<i!=0)
           printf("r");
        else
            printf("-");

        if(st.st_mode&1<<(i-1)!=0)
            printf("w");
        else
            printf("-");
        if(st.st_mode&1<<(i-2)!=0)
            printf("x");
        else
            printf("-");

    }
//用户名
    struct passwd *pw=getpwuid(st.st_uid);
//链接数    
printf(" %ld",st.st_nlink);
    printf(" %s ",pw->pw_name);
struct group *gr =getgrgid(st.st_gid);
//用户组名    
printf( "%s",gr->gr_name);
//长度    
printf(" %ld",st.st_size);
    char arr[100]={0};
//获取时间
    strcpy(arr,ctime(&st.st_mtime));
    if(arr[strlen(arr)-1]=='\n')
        arr[strlen(arr)-1]='\0';
    printf(" %s ",arr);
    puts("");
    return 0;

}

2、目录文件函数

    1opendir

       作用:

           打开一个目录文件

       头文件

           #include<sys/types.h>

           #include<dirent.h>

       函数原型:

           DIR *opendir(const char *name)

       参数:

           name:目录文件

       返回值:

           成功返回目录流指针,失败返回 NULL并设置错误号。

    2、readdir

    作用:

       读取目录当中一个文件的属性

    头文件:

       dirent.h

    函数文件

       struct dirent *readdir(DIR * dirp);

    参数:

       dirp:想要操作的目录流指针

    返回值:

       成功返回读取到的文件的相关信息的地址,被保存在一个struct dirent结构体中,失败或者读完了所有文件的返回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 */

           };

       3、closedir

       作用:

              关闭目录流指针

       头文件:

              #include <sys/types.h>

                  #include <dirent.h>

       函数原型:

              int closedir(DIR *dirp);

       参数:

              dirp:目录流指针

       返回值:

       成功返回0,失败返回-1并设置错误号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

clown_30

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值