学习IO(文件IO)

文件IO

一、概念

在posix(可移植操作系统接口)中定义的一组输入输出的函数

二、 特点

  1. 没有缓冲机制,每次操作都会经过系统调用,效率比较低
  2. 围绕文件描述符进行操作,文件描述符是非负整数, 0、1、2.....
  3. 默认打开三个文件描述符,0(标准输入)、1(标准输出)、2(标准错误)
  4. 除目录外其他任意类型文件都可以操作 

三、函数

3.1打开文件 open

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

功能:打开文件

参数:

        pathname:文件路径名

        flags:打开文件的方式

                O_RDONLY:只读

                O_WRONLY:只写

                O_RDWR:可读可写

                O_CREAT:创建

                O_TRUNC:清空

                O_APPEND:追加

返回值:

        成功:文件描述符

        失败:-1

示例:

 

当打开方式为:O_CREAT的时候,才会需要使用第三个参数

 

 

补充:
  1. 当第二个参数中有O_CREAT选项时,需要给open函数传递第三个参数,指定创建文件的权限 ,open(file, xx|O_CREAT|xx, 0666);
  2. 实际创建出来的文件权限为指定权限值&(~umask) //umask为文件权限掩码,通过umask命令可以查看
  3. 打开文件方式对应表:

标准IO

文件IO

r

O_RDONLY

r+

O_RDWR

w

O_WRONLY|O_TRUNC|O_CREAT

w+

O_RDWR|O_TRUNC|O_CREAT

a

O_APPEND|O_CREAT|O_WRONLY

a+

O_RDWR|O_APPEND|O_CREAT

3.2关闭文件 close

int close ( int fd );

3.3读文件 read

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

功能:从一个已打开的可读文件中读取数据

参数:

        fd 文件描述符

        buf 存放位置

        count 期望的个数

返回值:

        成功:实际读到的个数

        返回-1:表示出错,并设置errno号

        返回0:表示读到文件结尾

 

3.4写文件 write

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

功能:向指定文件描述符中,写入 count个字节的数据。

参数:

        fd 文件描述符

        buf 要写的内容

        count 期望值

返回值:

        成功:实际写入数据的个数

        失败 : -1

 

3.5文件定位操作

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

功能:设定文件的偏移位置

参数:

        fd:文件描述符

        offset偏移量

                正数:向文件结尾位置移动

                负数:向文件开始位置

        whence 相对位置

                SEEK_SET 开始位置

                SEEK_CUR 当前位置

                SEEK_END 结尾位置

返回值:

        成功:文件的当前位置

 

练习:实现如下功能

1-- 打开一个文件,不存在创建,存在清零

2-- 向文件中第 10 位置处写一个字符,

3-- 在文件此时的位置,后 20个位置处,写一行字符串hello进去

4-- 求文件的长度。

 

#include "head.h"
int main(int argc, char const *argv[])
{
    int fd;
    char buf[32] = "";
    fd = open("./test.c", O_RDWR | O_TRUNC | O_CREAT);

    if (fd < 0)
    {
        perror("open err");
        return -1;
    }
    lseek(fd, 10, SEEK_SET);
    write(fd, "a", 1);
    lseek(fd, 20, SEEK_CUR);
    write(fd, "hello", 5);
    off_t off = lseek(fd, 0, SEEK_END);
    printf("%ld\n", off);
    close(fd);
    return 0;
}

3.6文件属性获取

int stat ( const char * path , struct stat * buf );

功能:获取文件属性

参数:

        path:文件路径名

        buf:保存文件属性信息的结构体

返回值:

        成功:0

        失败:-1

struct stat

{

        dev_t st_dev; /* 设备ID */

        ino_t st_ino; /* inode号 */

        mode_t st_mode; /* 文件类型和权限 */

        nlink_t st_nlink; /* 硬链接数 */

        uid_t st_uid; /* 用户ID */

        gid_t st_gid; /* 组ID */

        off_t st_size; /* 大小 */

        time_t st_atime; /* 最后访问时间 */

        time_t st_mtime; /* 最后修改时间 */

        time_t st_ctime; /* 最后状态改变时间 */

};

示例:

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

int main(int argc, char const *argv[])
{
    struct stat st;
    stat("test.c", &st);

    printf("%ld\n", st.st_ino);
    printf("%ld\n", st.st_size);
    printf("%ld\n", st.st_nlink);
    
    // 文件类型判断
    // __S_IFMT:文件类型掩码  S_IFREG:普通文件 S_IFDIR:目录
    if((st.st_mode & __S_IFMT) == S_IFREG)
        putchar('-');
    else if((st.st_mode & __S_IFMT) == S_IFDIR)
        putchar('d');

    // 判断文件权限
    // 用户读权限
    if((st.st_mode & S_IRUSR) > 0)
        putchar('r');
    else
        putchar('-');
    
    // 用户写权限
    if((st.st_mode & S_IWUSR) > 0)
        putchar('w');
    else
        putchar('-');

    // 最后一次修改的时间
        // 这个得到的是秒的形式
        // 我们可以借助localtime函数
    printf("%ld\n", st.st_mtime); 

    // 用户名获取
    getpwuid();
    // 获取组名
    getgrgid();
    return 0;
}

3.7目录操作

围绕目录流进行操作,DIR *

DIR *opendir(const char *name);
功能:获得目录流
参数:要打开的目录
返回值:成功:目录流
       失败:NULL
       
struct dirent *readdir(DIR *dirp);
功能:读目录
参数:要读的目录流
返回值:成功:读到的信息    
      失败或读到目录结尾:NULL
返回值为结构体,该结构体成员为描述该目录下的文件信息

struct dirent {
        ino_t   d_ino;                   /* 索引节点号*/
        off_t   d_off;               /*在目录文件中的偏移*/
        unsigned short d_reclen;    /* 文件名长度*/
        unsigned char  d_type;      /* 文件类型 */
        char    d_name[256];      /* 文件名 */
};

int closedir(DIR *dirp);
功能:关闭目录
参数:dirp:目录流

示例:

 

四、标准IO和文件IO的区别

标准IO

文件IO

概念

在C库中定义的一组输入输出的函数

在posix中定义

特点

  1. 围绕流操作 FILE *
  2. 有缓冲区,减少系统调用,提高效率
  3. 默认打开三个流
  4. 只操作普通文件
  1. 围绕文件描述符操作
  2. 无缓冲区,每次操作都引用系统调用
  3. 默认打开三个文件描述符
  4. 除目录外其他文件

函数

打开文件:fopen

关闭文件:fclose

读写文件:fgetc/fputc

文件定位:fseek/rewind/ftell

打开文件:open

关闭文件:close

读写文件:read/write

文件定位:lseek

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值