精华内容
下载资源
问答
  • 标准IO和文件IO

    2019-08-20 11:54:32
    标准IO和文件IO的使用和相关知识

    IO:input output

    标准I/O

    头文件 #include <stdio.h>

    • 打开文件:

       FILE *fopen(const char *path, const char *mode);
      

      FILE *:流,本质是一个结构体指针,指向一个描述打开的文件属性的结构体
      文件指针: 记录当前打开的文件 读写的位置,读和写均会移动为文件指针

      参数:
      path:文件的路径
      mode:打开模式
      “r” :只读方式打开,打开后文件指针在文件开始位置,若文件不存在,出错
      “r+”:读写方式,继承r的属性
      “w” :只写方式打开,清空文件长度,文件不存在就创建
      “w+”:读写方式,继承w的属性
      “a” :追加方式打开,文件指针在文件末尾,只写
      “a+”:继承"a"的属性,可读可写

    • 文件的读写:

       //读取字符
       int fgetc(FILE *stream);
       //按行读取字符
       char *fgets(char *s, int size, FILE *stream);
       //返回值为EOF,说明已读取到文件末尾
       //写入字符
       int fputc(int c, FILE *stream);
       //按行写入字符
       int fputs(const char *s, FILE *stream);
       
       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
       size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
      
    • 缓存的设置和修改:

       int setvbuf(FILE *stream, char *buf, int mode, size_t size);
      

      文件指针偏移:每次读写文件,文件指针都会发生偏移,使用fseek设置文件指针位置。

       int fseek(FILE *stream, long offset, int whence);
       long ftell(FILE *stream); 获得当前文件指针的位置
      

      stream:流
      offset:偏移量
      whence:基准点
      文件开头 SEEK_SET
      当前位置 SEEK_CUR
      文件末尾 SEEK_END

    文件I/O

    • 打开文件:

       #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_APPEND:追加
      O_CREAT:文件不存在就创建
      O_EXCL : 文件不存在就报错
      O_TRUNC:文件打开时截短文件
      mode:用于创建文件
      (O_CREAT),指定文件的权限 如:0666 0777

    在这里插入图片描述

    • 文件的读写

       #include <unistd.h>
       ssize_t read(int fd, void *buf, size_t count);
      

      fd:要读的文件的文件描述符
      buf:容器,存放读到的数据
      count:读取的字节数
      返回值:ssize_t >0 读到的字节数 == 0 文件末尾 <0 出错

       #include <unistd.h>
       ssize_t write(int fd, const void *buf, size_t count);
      

      fd:要写的文件的文件描述符
      buf:容器,存放要写入的数据
      count:要写入的字节数
      ssize_t 实际写入的子节数

    • 目录操作

       #include <sys/types.h>
       #include <dirent.h>
       
       DIR *opendir(const char *name);
      

      返回值 DIR 目录流
      name:目录路径

       struct dirent *readdir(DIR *dirp);
       struct dirent {
       	               ino_t          d_ino;       /* inode number */
       	               off_t          d_off;       /* not an offset; see NOTES */
       	               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]; /* filename */
       	           };
      

      该函数可以反复调用,以获取其他文件,直到返回NULL

    • 文件属性

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>
       
       int stat(const char *pathname, struct stat *buf); 
      

      pathname:文件名 ./a.txt
      buf:文件属性容器
      0 成功 -1失败 errno

       struct stat {
                  dev_t     st_dev;         /* ID of device containing file */
                  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 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
              };
       	struct timespec {
       	time_t tv_sec; // seconds
       	long tv_nsec; // and nanoseconds
       	};
      
    • 其他相关知识:

      文件:相关数据的集合
      文件:存储,一般要非易失介质
      文件系统:文件的组织和存储

      Linux 文件的分类: 7类文件类型
      普通文件 .txt .mp3 -
      目录文件 d
      字符型设备文件 c
      块设备文件 b
      链接文件 l
      管道文件 p
      套接字文件 s

      文件操作:操作函数 调用
      函数5要素:
      1、头文件
      2、函数原型
      3、参数
      4、返回值
      5、作用和功能、注意事项

      文件受操作系统保护,文件系统
      文件IO:文件系统带的操作文件函数,系统调用
      1、直接
      2种途径:
      标准IO:C库所带的,操作文件的一些函数
      1、带缓冲的IO,提高效率 刷新(冲洗)缓冲区
      3种缓冲刷新机制:
      全缓冲
      行缓冲 ‘\n’
      不缓冲

      2、增强程序的可移植性

      终端流:
      标准输入流: stdin 行缓冲
      标准输出流: stdout 行缓冲
      标准错误流: stderr 不缓冲

      全局错误变量 errno 记录最近的一次错误
      perror(); strerror();

      流末尾判定函数:
      int feof(FILE *stream);
      手动刷新流
      fflush()

      对于一个流的刷新方法:
      1、手动刷新,fflush函数
      2、关闭该流,也可以刷新
      3、设置流为无缓冲类型 setvbuf 函数

      使用"w" 属性创建文件后,文件的属性问题?
      0666属性创建 wr-wr-wr-
      权限掩码 umask
      0666 & ~umask = 最终权限
      0666 & ~0077 = 0600

      time
      localtime
      #include <time.h>
      time_t time(time_t *tloc);
      返回一个秒数从 1970-1-1 0:0:0 到现在的秒数

       struct tm *localtime(const time_t *timep);
       	struct tm {
                      int tm_sec;    /* Seconds (0-60) */
                      int tm_min;    /* Minutes (0-59) */
                      int tm_hour;   /* Hours (0-23) */
                      int tm_mday;   /* Day of the month (1-31) */
                      int tm_mon;    /* Month (0-11) */
                      int tm_year;   /* Year - 1900 */
                      int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
                      int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
                      int tm_isdst;  /* Daylight saving time */
                  };
      

      文件空洞:只针对普通文件有效;
      移动文件指针,到文件末尾之后,继续往后移动,超过文件末尾,写入数据就会形成文件空洞。
      默认填充数值0

      st_mode 属性获取文件的类型
      001 000 000 110 110 100
      其他用户对该文件权限
      获取文件的权限
      110 110 100

       #include <sys/types.h>
       #include <pwd.h>
       //根据用户uid/gid 获取用户名
       struct passwd *getpwuid(uid_t uid);
       struct passwd {
                      char   *pw_name;       /* username */
                      char   *pw_passwd;     /* user password */
                      uid_t   pw_uid;        /* user ID */
                      gid_t   pw_gid;        /* group ID */
                      char   *pw_gecos;      /* user information */
                      char   *pw_dir;        /* home directory */
                      char   *pw_shell;      /* shell program */
                  };
      

    实例:Linux命令 copy的实现
    实例:Linux命令 ls -a ls -l的实现

    展开全文
  • 嵌入式标准IO和文件IO

    2019-07-30 01:05:19
    标准IO文件IO的区别 文件IO 标准IO 直接调用内核提供的系统调用函数,头文件是unistd.h 间接调用系统调用函数,头文件是stdio.h

    在这里插入图片描述
    标准IO
    与文件IO的区别

    文件IO 标准IO
    直接调用内核提供的系统调用函数,头文件是unistd.h 间接调用系统调用函数,头文件是stdio.h
    展开全文
  • 标准IO和文件IO区别

    2019-08-01 20:58:01
    先来了解下什么是标准IO以及文件IO标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO...

    先来了解下什么是标准IO以及文件IO。

    标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存。

    (1)全缓存:当填满标准IO缓存后才进行实际的IO操作。
    (2)行缓存:当输入或输出中遇到新行符时,标准IO库执行IO操作。
    (3)不带缓存:stderr就是了。

    文件IO:文件IO称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于linix或unix平台。

    2区别

    首先:两者一个显著的不同点在于,标准I/O默认采用了缓冲机制,比如调用fopen函数,不仅打开一个文件,而且建立了一个缓冲区(读写模式下将建立两个缓冲区),还创建了一个包含文件和缓冲区相关数据的数据结构。低级I/O一般没有采用缓冲,需要自己创建缓冲区,不过其实在linix或unix系统中,都是有使用称为内核缓冲的技术用于提高效率,读写调用是在内核缓冲区和进程缓冲区之间进行的数据复制。

    其次从操作的设备上来区分,文件I/O主要针对文件操作,读写硬盘等,它操作的是文件描述符,标准I/O针对的是控制台,打印输出到屏幕等,它操作的是字符流。对于不同设备得特性不一样,必须有不同api访问才最高效。

    最后来看下他们使用的函数

    标准IO 文件IO
    fopen,freopen,fdopen open
    fclose close
    getc,fget,getchar,fgets,gets,fread read
    putc,fputc,putchar,fputs,puts,fwrite write

    1.fopen与open

    标准I/O使用fopen函数打开一个文件:

    FILE* fp=fopen(const char* path,const char *mod)

    其中path是文件名,mod用于指定文件打开的模式的字符串,比如"r",“w”,“w+”,"a"等等,可以加上字母b用以指定以二进制模式打开(对于 *nix系统,只有一种文件类型,因此没有区别),如果成功打开,返回一个FILE文件指针,如果失败返回NULL,这里的文件指针并不是指向实际的文 件,而是一个关于文件信息的数据包,其中包括文件使用的缓冲区信息。

    文件IO使用open函数用于打开一个文件:

    int fd=open(char *name,int how);

    与fopen类似,name表示文件名字符串,而how指定打开的模式:O_RDONLY(只读),O_WRONLY(只写),O_RDWR (可读可写),还有其他模式请man 2 open。成功返回一个正整数称为文件描述符,这与标准I/O显著不同,失败的话返回-1,与标准I/O返回NULL也是不同的。

    2.fclose与close

    与打开文件相对的,标准I/O使用fclose关闭文件,将文件指针传入即可,如果成功关闭,返回0,否则返回EOF
    比如:

    if(fclose(fp)!=0)
    printf(“Error in closing file”);

    而文件IO使用close用于关闭open打开的文件,与fclose类似,只不过当错误发生时返回的是-1,而不是EOF,成功关闭同样是返回0。C语言用error code来进行错误处理的传统做法。

    1. 读文件,getc,fscanf,fgets和read

    标 准I/O中进行文件读取可以使用getc,一个字符一个字符的读取,也可以使用gets(读取标准io读入的)、fgets以字符串单位进行读取(读到遇 到的第一个换行字符的后面),gets(接受一个参数,文件指针)不判断目标数组是否能够容纳读入的字符,可能导致存储溢出(不建议使用),而fgets使用三个参数:
    char * fgets(char *s, int size, FILE *stream);

    第一个参数和gets一样,用于存储输入的地址,第二个参数为整数,表示输入字符串的最大长度,最后一个参数就是文件指针,指向要读取的文件。最 后是fscanf,与scanf类似,只不过增加了一个参数用于指定操作的文件,比如fscanf(fp,"%s",words)
    文件IO中使用read函数用于读取open函数打开的文件,函数原型如下:

    ssize_t numread=read(int fd,void *buf,size_t qty);

    其中fd就是open返回的文件描述符,buf用于存储数据的目的缓冲区,而qty指定要读取的字节数。如果成功读取,就返回读取的字节数目(小于等于qty)

    1. 判断文件结尾

    如果尝试读取达到文件结尾,标准IO的getc会返回特殊值EOF,而fgets碰到EOF会返回NULL,而对于*nix的read函数,情况有所不 同。read读取qty指定的字节数,最终读取的数据可能没有你所要求的那么多(qty),而当读到结尾再要读的话,read函数将返回0.

    1. 写文件:putc,fputs,fprintf和write

    与读文件相对应的,标准C语言I/O使用putc写入字符,比如:

    putc(ch,fp);

    第一个参数是字符,第二个是文件指针。而fputs与此类似:

    fputs(buf,fp);

    仅仅是第一个参数换成了字符串地址。而fprintf与printf类似,增加了一个参数用于指定写入的文件,比如:

    fprintf(stdout,“Hello %s.\n”,“dennis”);

    切记fscanf和fprintf将FILE指针作为第一个参数,而putc,fputs则是作为第二个参数。

    在文件IO中提供write函数用于写入文件,原型与read类似:

    ssize_t result=write(int fd,void *buf ,size_t amt);

    fd是文件描述符,buf是将要写入的内存数据,amt是要写的字节数。如果写入成功返回写入的字节数,通过result与amt的比较可以判断是否写入正常,如果写入失败返回-1

    1. 随机存取:fseek()、ftell()和lseek()

    标准I/O使用fseek和ftell用于文件的随机存取,先看看fseek函数原型

    int fseek(FILE *stream, long offset, int whence);

    第一个参数是文件指针,第二个参数是一个long类型的偏移量(offset),表示从起始点开始移动的距离。第三个参数就是用于指定起始点的模式,stdio.h指定了下列模式常量:

    SEEK_SET 文件开始处
    SEEK_CUR 当前位置
    SEEK_END 文件结尾处

    看几个调用例子:
    fseek(fp,0L,SEEK_SET); //找到文件的开始处
    fseek(fp,0L,SEEK_END); //定位到文件结尾处
    fseek(fp,2L,SEEK_CUR); //文件当前位置向前移动2个字节数

    而ftell函数用于返回文件的当前位置,返回类型是一个long类型,比如下面的调用:

    fseek(fp,0L,SEEK_END);//定位到结尾
    long last=ftell(fp); //返回当前位置

    那么此时的last就是文件指针fp指向的文件的字节数。

    与标准I/O类似,*nix系统提供了lseek来完成fseek的功能,原型如下:

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

    fildes是文件描述符,而offset也是偏移量,whence同样是指定起始点模式,唯一的不同是lseek有返回值,如果成功就 返回指针变化前的位置,否则返回-1。whence的取值与fseek相同:SEEK_SET,SEEK_CUR,SEEK_END,但也可以用整数 0,1,2相应代替

    展开全文
  • 标准IO和文件IO_01.jpg

    2020-02-02 01:55:04
    嵌入式学习笔记(一)——标准IO文件IO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!...
  • 标准IO和文件IO解析

    2018-05-24 14:26:55
    标准IO简介ANSI C建立的一个标准I/O模型,是一个标准函数包stdio.h头文件中的定义带缓冲IO可移植性通过FILE 文件指针访问2. 标准IO缓冲全缓存:当填满I/O才进行实际的I/O操作行缓存:当在输入输出中遇到新行...

    一. 架构图
    二. 标准IO
    1. 标准IO简介

    • ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义
    • 带缓冲IO
    • 可移植性
    • 通过FILE 文件指针访问
    2. 标准IO缓冲

    • 全缓存:当填满I/O才进行实际的I/O操作
    • 行缓存:当在输入和输出中遇到新行符号('\n'),进行I/O操作,例如:stdout
    • 不带缓存:标准I/O不对字符进行缓冲,例如stderr
    3. 如何理解缓存类型

        要理解标准IO缓存,得理解FILE文件指针(struct _IO_FILE结构体),标准IO接口操作的是FILE文件指针,FILE文件指针定义了很多变量,包括读写缓冲区指针以及缓冲区类型标志。

        我们可以通过setvbuf函数设置缓存类型:

        int setvbuf(FILE *fp, char *buf, int mode, size_t size) 

        mode :_IOFBF 全缓存 _IOLBF 行缓存 _IONBF不带缓存

        实际上:stdout和stderr也是通过该接口进行设置,形成了不同的缓存类型。

    三. 文件IO
    1.文件IO简介

    • 低级磁盘I/O,遵循POSIX相关标准,任何兼容POSIX标准的操作系统上都支持文件I/O
    • 不带缓冲IO
    • 通过文件描述符访问
    2.文件IO工作原理

        文件IO实现用户空间数据和内核缓冲区数据的交互,标准IO和内核的交互也是通过文件IO进行,标准IO只有满足一定的条件才进行文件IO操作。

    四. 数据传输流程
    1.系统掉电后,文件数据丢失?

        实际工作中,我们会遇到这样的情况,我们按照标准的方式去操作IO,结果数据丢失了,比如我们调用fflush函数。

        我们先理解一下数据传输流程,用户数据调用标准I/O(fflush,或者缓冲区自动刷新)仅仅只是进行了一次实际I/O操作(文件IO:write),只是把数据写入内核缓冲区,掉电后,内核缓冲区数据并没有写入磁盘,内核缓冲区会执行fsync操作(我们可以手动执行sync),这样才能真正的把数据写入磁盘,掉电后才不会丢失。






    展开全文
  • 标准IO和文件IO复习

    2017-02-12 15:23:39
    标准IO:库,带缓冲的IO(减少系统调用的次数),通过流操作文件,高级IO。 文件IO:系统调用,不带缓存(内核缓存), 通过文件描述符操作文件,低级IO。
  • 标准IO和文件IO的比较

    2014-12-03 09:44:57
    先来了解下什么是标准IO以及文件IO标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度...
  • https://blog.csdn.net/yang2011079080010/article/details/53759759 ... 对于操作系统而言,I/O操作可以分为两类,一类是带缓存的IO,又称为标准IO(C标准库中提供了标准IO库,即stdio),它实现了跨平台的...
  • c++标准IO和文件IO

    2018-07-20 16:48:26
    #define _CRT_SECURE_NO_WARNINGS   #include &lt;iostream&gt; #include &...//文件读写头文件 using namespace std;   int main() { char a; char buf[256] = { 0 };   ...
  • 一、先来了解下什么是文件I/O和标准I/O: 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务...
  • 标准IO:ANSI C中定义的一系列用于对IO操作的函数,(只能访问普通文件) 知识点:流指针:文件的操作,标准IO通常通过一个FILE的结构体,称这个结构体为流,他的指针称为流指针(系统自动打开的流:标准输出stdout...
  • 一、什么是文件I/O和标准I/O: 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定...
  • 首先了解下什么是标准IO以及文件IO标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度...
  • 标准IO和文件IO的区别

    千次阅读 2010-02-04 09:27:00
    作者:王珊珊 华清远见嵌入式学院讲师先来了解下什么是标准IO以及文件IO。 标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很...
  • 标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存。  (1...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,157
精华内容 1,262
关键字:

标准io和文件io