当前位置: 首页 > news >正文

山西城乡和住房建设厅网站北京西站列车时刻表

山西城乡和住房建设厅网站,北京西站列车时刻表,房地产最新消息利好政策,互联网行业是做什么的一、文件I/O基础 文件 I/O 指的是对文件的输入/输出操作#xff0c;就是对文件的读写操作。Linux 下一切皆文件。 1.1 文件描述符 在 open函数执行成功的情况下#xff0c; 会返回一个非负整数#xff0c; 该返回值就是一个文件描述符#xff08;file descriptor#x…一、文件I/O基础 文件 I/O 指的是对文件的输入/输出操作就是对文件的读写操作。Linux 下一切皆文件。 1.1 文件描述符 在 open函数执行成功的情况下 会返回一个非负整数 该返回值就是一个文件描述符file descriptor 这说明文件描述符是一个非负整数 对于 Linux 内核而言所有打开的文件都会通过文件描述符进行索引。 在 Linux 系统中一个进程可以打开的文件数是有限制的。默认1024个0~1023系统占用系统标准输入0、 标准输出1以及标准错误2。 通过 ulimit 命令来查看进程可打开的最大文件数 ulimit -n Tips每一个硬件设备都会对应于linux系统下的某一个文件设备文件应用程序对设备文件进行读写操作来使用或控制硬件设备。  1.1.1 复制文件描述符 复制得到的文件描述符和旧的文件描述符拥有相同的权限但是号是不一样的。可以多次复制。 “复制”的含义实则是复制文件表。 dup 函数用于复制文件描述符可以实现两个写入的接续进行。 #include unistd.h int dup(int oldfd);函数参数和返回值含义如下 oldfd 需要被复制的文件描述符。 返回值 成功时将返回一个新的文件描述符由操作系统分配分配置原则遵循文件描述符分配原则 如果复制失败将返回-1并且会设置 errno 值。 dup2也可以复制文件描述符并且可以手动指定文件描述符。 #include unistd.h int dup2(int oldfd, int newfd);函数参数和返回值含义如下 oldfd 需要被复制的文件描述符。 newfd 指定一个文件描述符需要指定一个当前进程没有使用到的文件描述符。 返回值 成功时将返回一个新的文件描述符也就是手动指定的文件描述符 newfd如果复制失败将返 回-1并且会设置 errno 值。 1.2 open打开文件文件权限 可以通过man命令查看系统调用的信息。 man 2 open/* man 命令后面跟着两个参数: 数字 2 表示系统调用 Linux 命令对应数字 1以及标准 C 库函数对应数字 3所对应的帮助信息。 最后一个参数 open 表示需要查看的系统调用函数名。 */ #include sys/types.h #include sys/stat.h #include fcntl.hint open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);int creat(const char *pathname, mode_t mode);int openat(int dirfd, const char *pathname, int flags); int openat(int dirfd, const char *pathname, int flags, mode_t mode);函数参数和返回值含义如下 pathname  字符串类型用于标识需要打开或创建的文件可以包含路径绝对路径或相对路径 信息譬如./src_file当前目录下的 src_file 文件、 /home/dengtao/hello.c等如果 pathname 是一个符号链接会对其进行解引用。 flags  调用 open 函数时需要提供的标志 包括文件访问模式标志以及其它文件相关标志这些标志使用宏定义进行描述都是常量 open 函数提供了非常多的标志我们传入 flags 参数时既可以单独使用某一个标志也可以通过位或运算| 将多个标志进行组合。 这些标志介绍如下 O_RDONLY只读。    O_WRONLY只写。    O_RDWR可读可写。    O_CREAT不存在则创建。    O_DIRECTORYpathname指向的不是目录调用open失败。    O_EXCL与O_CREAT一起使用判断是否已经存在。    O_NOFOLLOWpathname是一个符号链接将不对其进行解引用直接返回错误。O_TRUNC 将文件原本的内容全部丢弃文件大小变为 0。O_APPEND 调用 open 函数打开文件当每次使用 write()函数对文件进行写操作时都会自动把文件当前位置偏移量移动到文件末尾 从文件末尾开始写入数据也就是意味着每次写入数据都是从文件末尾开始。使用了 O_APPEND 标志即使是通过 lseek 函数也是无法修改写文件时对应的位置偏移量。O_DSYNC每个write()之后自动调用fdatasync()进行数据同步O_SYNC每个write()之后自动调用fsync()进行数据同步 mode  此参数用于指定新建文件的访问权限只有当 flags 参数中包含 O_CREAT 或 O_TMPFILE 标志 时才有效O_TMPFILE 标志用于创建一个临时文件。 权限对于文件来说是一个很重要的属性那么在 Linux系统中我们可以通过 touch 命令新建一个文件此时文件会有一个默认的权限如果需要修改文件权限可通过 chmod 命令对文件权限进行修改譬如在 Linux 系统下我们可以使用ls -l命令来查看到文件所对应的权限。mode 参数的类型是 mode_t(u32) S---这 3 个 bit 位用于表示文件的特殊权限文件特殊权限一般用的比较少 U---这 3 个 bit 位用于表示文件所属用户的权限即文件或目录的所属者 G---这 3 个 bit 位用于表示同组用户group的权限即与文件所有者有相同组 ID 的所有用户 O---这 3 个 bit 位用于表示其他用户的权限 3 个 bit 位中按照 rwx 顺序来分配权限位。例如7八进制可读可写可执行5八进制可读可执行。 open 函数文件权限宏通过位或可以组合 宏定义说明S_IRUSR允许文件所属者读文件S_IWUSR允许文件所属者写文件S_IXUSR允许文件所属者执行文件S_IRWXU允许文件所属者读、写、执行文件S_IRGRP允许同组用户读文件S_IWGRP允许同组用户写文件S_IXGRP允许同组用户执行文件S_IRWXG允许同组用户读、写、执行文件S_IROTH允许其他用户读文件S_IWOTH允许其他用户写文件S_IXOTH允许其他用户执行文件S_IRWXO允许其他用户读、写、执行文件S_ISUID S_ISGID S_ISVTXset-user-ID特殊权限 set-group-ID特殊权限 sticky特殊权限 返回值 成功将返回文件描述符文件描述符是一个非负整数失败将返回-1。 1.3 write写文件 #include unistd.h ssize_t write(int fd, const void *buf, size_t count); 函数参数和返回值含义如下fd open之后返回的文件描述符。 关于文件描述符需要将进行写操作的文件所对应的文件描述符传递给 write 函数。buf 指定写入数据对应的缓冲区。count 指定写入的字节数。返回值 如果成功将返回写入的字节数0 表示未写入任何字节如果此数字小于 count 参数这不是错误譬如磁盘空间已满可能会发生这种情况如果写入出错则返回-1。 一般是默认写文件写到文件起始位置。如果当前位置偏移量为 1000 个字节处调用 write()写入或 read()读取 500 个字节之后当前位置偏移量将会移动到 1500 个字节处。 1.4 read读文件 #include unistd.h ssize_t read(int fd, void *buf, size_t count); 函数参数和返回值含义如下fd 文件描述符。与 write 函数的 fd 参数意义相同。 buf 指定用于存储读取数据的缓冲区。 count 指定需要读取的字节数。 返回值 如果读取成功将返回读取到的字节数实际读取到的字节数没那么多可以读的字节可能会小于 count 参数指定的字节数也有可能会为 0。 1.5 close关闭文件 #include unistd.h int close(int fd); fd 文件描述符需要关闭的文件所对应的文件描述符。返回值 如果成功返回 0如果失败则返回-1。 进程终止的时候内核会自动关闭进程打开的所有文件。显式关闭不再需要的文件描述符是良好的编程习惯文件描述符是有限资源。 1.6 lseek 系统会自动记录读写位置偏移量。文件第一个字节数据的位置偏移量为 0。 当打开文件时会将读写偏移量设置为指向文件开始位置处以后每次调用 read()、 write()将自动对其进行调整以指向已读或已写数据后的下一字节因此连续的调用 read()和 write()函数将使得读写按顺序递增对文件进行操作。 #include sys/types.h #include unistd.h off_t lseek(int fd, off_t offset, int whence); fd 文件描述符。offset 偏移量以字节为单位。whence 用于定义参数 offset 偏移量对应的参考值 该参数为下列其中一种宏定义 SEEK_SET读写偏移量将指向 offset 字节位置处从文件头部开始算 SEEK_CUR读写偏移量将指向当前位置偏移量 offset 字节位置处 offset 可以为正、也可以为负如果是正数表示往后偏移如果是负数则表示往前偏移SEEK_END读写偏移量将指向文件末尾 offset 字节位置处同样 offset 可以为正、也可以为负如果是正数表示往后偏移、如果是负数则表示往前偏移。 返回值 成功将返回从文件头部开始算起的位置偏移量字节为单位 也就是当前的读写位置 发生错误将返回-1。 二、文件I/O深入 2.1 Linux系统如何管理文件 2.1.1 静态文件和inode 静态文件文件存放在磁盘文件系统中并且以一种固定的形式进行存放。 文件储存在硬盘上 硬盘的最小存储单位叫做“扇区” Sector 每个扇区储存 512 字节相当于 0.5KB操作系统读取硬盘的时候不会一个个扇区地读取这样效率太低而是一次性连续读取多个扇区即一次性读取一个“块” block。这种由多个扇区组成的“块” 是文件存取的最小单位。 “块” 的大小最常见的是 4KB即连续八个 sector 组成一个 block。 磁盘两个区域数据区用于存储文件中的数据inode区用于存放 inode tableinode 表。 通过ls -i命令或stat 命令查看文件的 inode 编号。 打开一个文件系统内部会将这个过程分为三步 1) 系统找到这个文件名所对应的 inode 编号 2) 通过 inode 编号从 inode table 中找到对应的 inode 结构体 3) 根据 inode 结构体中记录的信息确定文件数据所在的 block并读出数据。 2.1.2 文件打开时的状态 当我们调用 open 函数去打开文件的时候内核会申请一段内存一段缓冲区 并且将静态文件的数据内容从磁盘这些存储设备中读取到内存中进行管理、 缓存也把内存中的这份文件数据叫做动态文件、内核缓冲区。 读写动态文件后动态文件与静态文件不同步内核会将动态文件更新至磁盘设备中。 在 Linux 系统中 内核会为每个进程设置一个专门的数据结构用于管理该进程譬如用于记录进程的状态信息、运行特征等我们把这个称为进程控制块Process control block缩写PCB 。 PCB 数据结构体中有一个指针指向了文件描述符表File descriptors 文件描述符表中的每一个元素索引到对应的文件表File table文件表也是一个数据结构体其中记录了很多文件相关的信息譬如文件状态标志、 引用计数、 当前文件的读写偏移量以及 i-node 指针指向该文件对应的 inode等 进程打开的所有文件对应的文件描述符都记录在文件描述符表中每一个文件描述符都会指向一个对应的文件表。 2.2 返回错误处理与errno errno 本质上是一个 int 类型的变量用于存储错误编号 但是需要注意的是并不是执行所有的系统调用或 C 库函数出错时操作系统都会设置 errno。 通过man命令可以查询返回值。 #include errno.h 2.2.1 strerror函数C库函数 将对应的 errno 转换成适合我们查看的字符串信息 #include string.h char *strerror(int errnum);函数参数和返回值如下 errnum 错误编号 errno。 返回值 对应错误编号的字符串描述信息。 2.2.2 perror函数C库函数 调用此函数不需要传入 errno函数内部会自己去获取 errno 变量的值 调用此函数会直接将错误提示字符串打印出来而不是返回字符串除此之外还可以在输出的错误提示字符串之前加入自己的打印信息。perror 函数会在附加信息后面自动加入冒号和空格以区分。 #include stdio.h void perror(const char *s);函数参数和返回值含义如下 s 在错误提示字符串信息之前可加入自己的打印信息也可不加不加则传入空字符串即可。 返回值 void 无返回值。 2.3终止进程 终止进程的方法 main 函数中运行 return调用 Linux 系统调用_exit()或_Exit()调用 C 标准库函数 exit()。 2.3.1 _exit、_Exit 调用_exit()函数会清除其使用的内存空间并销毁其在内核中的各种数据结构 关闭进程的所有文件描述符 并结束进程、将控制权交给操作系统。_Exit与_exit一样。 _exit()和_Exit()是系统调用。 #include unistd.h void _exit(int status);status:0 表示正常结束、若为其它值则表示程序执行过程中检测到有错误发生。 2.3.2 exit exit()是一个标准 C 库函数。 #include stdlib.h void exit(int status); 2.4 空洞文件 使用lseek函数将文件偏移量6000字节超过文件长度4096字节write开始在6000写在4096~6000之间没有写入任何数据就形成了文件空洞那么该文件就是空洞文件。文件空洞不占用物理空间。直到在某个时刻对空洞部分进行写入数据时才会为它分配对应的空间但是空洞文件形成时逻辑上该文件的大小是包含了空洞部分的大小的这点需要注意。 空洞文件的用处对于很大的文件可以使用多线程进行分段读写。 使用 ls 命令查看到的大小是文件的逻辑大小包括了空洞部分大小和真实数据部分大小 du 命令查看到的大小是文件实际占用存储块的大小。 2.5 多次打开同一文件 一个进程内多次 open 打开同一个文件那么会得到多个不同的文件描述符 fd同理在关闭文件的时候也需要调用 close 依次关闭各个文件描述符。一个进程内多次 open 打开同一个文件在内存中并不会存在多份动态文件。一个进程内多次 open 打开同一个文件在不同文件描述符所对应的读写位置偏移量是相互独立的。分别写入同一文件现象是第二次写入的覆盖第一次写入的。想要接着写就用O_APPEND。 2.6 文件共享 同一个文件譬如磁盘上的同一个文件对应同一个 inode 被多个独立的读写体同时进行 IO 操作一个读写体操作文件尚未调用 close 关闭的情况下另一个读写体去操作文件。 常见的三种文件共享的实现方式 (1)同一个进程中多次调用 open 函数打开同一个文件。 多次调用open得到不同的文件描述符对应多个不同地文件表文件表索引到同一inode。 (2)不同进程中分别使用 open 函数打开同一个文件。 (3)同一个进程中通过 dupdup2函数对文件描述符进行复制。 2.7 竞争冒险 操作共享资源的两个进程或线程其操作之后的所得到的结果往往是不可预期的 因为每个进程或线程去操作文件的顺序是不可预期的即这些进程获得 CPU 使用权的先后顺序是不可预期的完全由操作系统调配 这就是所谓的竞争状态。 2.8 原子操作 所谓原子操作 是由多步操作组成的一个操作原子操作要么一步也不执行一旦执行 必须要执行完所有步骤不可能只执行所有步骤中的一个子集。 O_APPEND实现原子操作 移动当前写位置偏移量到文件末尾、写入数据”这两个操作步骤就组成了一个原子操作。 pread()和pwrite() #include unistd.h ssize_t pread(int fd, void *buf, size_t count, off_t offset); ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);函数参数和返回值含义如下 fd、 buf、 count 参数与 read 或 write 函数意义相同。 offset 表示当前需要进行读或写的位置偏移量。 返回值 返回值与 read、 write 函数返回值意义一样。 调用 pread 函数时无法中断其定位和读操作也就是原子操作不更新文件表中的当前位置偏移量。 创建一个文件O_EXCL 标志 文件创建的竞争状态 进程 A 和进程 B 都会创建出同一个文件同一个文件被创建两次这是不允许的。 将“判断文件是否存在、创建文件”这两个步骤合成为一个原子操作。 2.9 fcntl和ioctl #include unistd.h #include fcntl.hint fcntl(int fd, int cmd, ... /* arg */ )函数参数和返回值含义如下 fd 文件描述符。 cmd 对fd进行的操作命令。cmd 操作命令大致可以分为以下 5 种功能 1.复制文件描述符cmdF_DUPFD 或 cmdF_DUPFD_CLOEXEC 2.获取/设置文件描述符标志cmdF_GETFD 或 cmdF_SETFD 3.获取/设置文件状态标志cmdF_GETFL 或 cmdF_SETFL 4.获取/设置异步 IO 所有权cmdF_GETOWN 或 cmdF_SETOWN 5.获取/设置记录锁cmdF_GETLK 或 cmdF_SETLK fcntl 函数是一个可变参函数第三个参数需要根据不同的 cmd 来传入对应的实参配合 cmd 来使 用。 返回值 执行失败情况下返回-1并且会设置 errno执行成功的情况下其返回值与 cmd操作命 令有关譬如 cmdF_DUPFD复制文件描述符将返回一个新的文件描述符、 cmdF_GETFD获取文 件描述符标志将返回文件描述符标志、 cmdF_GETFL获取文件状态标志将返回文件状态标志等。 一般用于操作特殊文件或硬件外设。#include sys/ioctl.h int ioctl(int fd, unsigned long request, ...);函数参数和返回值含义如下 fd 文件描述符。 request 此参数与具体要操作的对象有关没有统一值 表示向文件描述符请求相应的操作 ... 此函数是一个可变参函数 第三个参数需要根据 request 参数来决定配合 request 来使用。 返回值 成功返回 0失败返回-1。 2.10 截断文件 截断如果文件目前的大小大于参数 length 所指定的大小则多余的数据将被丢失类似于多余的部分被“砍”掉了如果文件目前的大小小于参数 length 所指定的大小则将其进行扩展 对扩展部分进行读取将得到空字节\0。 #include unistd.h #include sys/types.h int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length);ftruncate()使用文件描述符 fd 来指定目标文件。 truncate()则直接使用文件路径 path 来指定目标文件。 使用 ftruncate()函数进行文件截断操作之前必须调用 open()函数打开该文件得到文件描述符并且必须要具有可写权限也就是调用 open()打开文件时需要指定 O_WRONLY 或 O_RDWR。 调用这两个函数并不会导致文件读写位置偏移量发生改变所以截断之后一般需要重新设置文件当前的读写位置偏移量以免由于之前所指向的位置已经不存在而发生错误譬如文件长度变短了文件当前所指向的读写位置已不存在。   三、标准I/O库 3.1 标准I/O库简介 stdio.h 标准 I/O 和文件 I/O 的区别如下 虽然标准 I/O 和文件 I/O 都是 C 语言函数但是标准 I/O 是标准 C 库函数而文件 I/O 则是 Linux系统调用标准 I/O 是由文件 I/O 封装而来标准 I/O 内部实际上是调用文件 I/O 来完成实际操作的可移植性标准 I/O 相比于文件 I/O 具有更好的可移植性通常对于不同的操作系统其内核向应用层提供的系统调用往往都是不同譬如系统调用的定义、功能、参数列表、返回值等往往都是不一样的而对于标准 I/O 来说由于很多操作系统都实现了标准 I/O 库标准 I/O 库在不同的操作系统之间其接口定义几乎是一样的所以标准 I/O 在不同操作系统之间相比于文件 I/O 具有更好的可移植性。性能、效率 标准 I/O 库在用户空间维护了自己的 stdio 缓冲区 所以标准 I/O 是带有缓存的而文件 I/O 在用户空间是不带有缓存的所以在性能、效率上标准 I/O 要优于文件 I/O。 3.2 FILE指针 对于标准 I/O 库函数来说它们的操作是围绕 FILE 指针进行的当使用标准 I/O 库函数打开或创建一个文件时会返回一个指向 FILE 类型对象的指针FILE * 使用该 FILE 指针与被打开或创建的文件相关联然后该 FILE 指针就用于后续的标准 I/O 操作使用标准 I/O 库函数进行 I/O 操作所以由此可知FILE 指针的作用相当于文件描述符。 FILE 是一个结构体数据类型它包含了标准 I/O 库函数为管理文件所需要的所有信息包括用于实际I/O 的文件描述符、指向文件缓冲区的指针、缓冲区的长度、当前缓冲区中的字节数以及出错标志等。 3.3 标准输入、标准输出和标准错误 #include unistd.h/* Standard file descriptors. */ #define STDIN_FILENO 0 /* Standard input. */ #define STDOUT_FILENO1 /* Standard output. */ #define STDERR_FILENO2 /* Standard error output. */ #include stdio.h/* Standard streams. */ extern struct _IO_FILE *stdin; /* Standard input stream. */ extern struct _IO_FILE *stdout; /* Standard output stream. */ extern struct _IO_FILE *stderr; /* Standard error output stream. */ /* C89/C99 say theyre macros. Make them happy. */ #define stdin stdin #define stdout stdout #define stderr stderr 3.4 fopen、fclose #include stdio.h FILE *fopen(const char *path, const char *mode);函数参数和返回值含义如下 path 参数 path 指向文件路径可以是绝对路径、也可以是相对路径。 mode 参数 mode 指定了对该文件的读写权限是一个字符串稍后介绍。 返回值 调用成功返回一个指向 FILE 类型对象的指针FILE *该指针与打开或创建的文件相关联 后续的标准 I/O 操作将围绕 FILE 指针进行。 如果失败则返回 NULL并设置 errno 以指示错误原因。 r O_RDONLYr O_RDWRw O_WRONLY| O_CREAT|O_TRUNCw   O_RDWR| O_CREAT|O_TRUNCa O_WRONLY| O_CREAT|O_APPENDa O_RDWR| O_CREAT|O_APEND 新建文件的权限默认值S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH (0666) #include stdio.h int fclose(FILE *stream); 3.5 fread、fwrite #include stdio.hsize_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);ptr fread()将读取到的数据存放在参数 ptr 指向的缓冲区中 size fread()从文件读取 nmemb 个数据项每一个数据项的大小为 size 个字节所以总共读取的数据大 小为 nmemb * size 个字节。 nmemb 参数 nmemb 指定了读取数据项的个数。 stream FILE 指针。 返回值 调用成功时返回读取到的数据项的数目数据项数目并不等于实际读取的字节数除非参数 size 等于 1如果发生错误或到达文件末尾则 fread()返回的值将小于参数 nmemb fread()不能区分文件结尾和错误。size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);ptr 将参数 ptr 指向的缓冲区中的数据写入到文件中。 size 参数 size 指定了每个数据项的字节大小与 fread()函数的 size 参数意义相同。 nmemb 参数 nmemb 指定了写入的数据项个数与 fread()函数的 nmemb 参数意义相同。 stream FILE 指针。 返回值 调用成功时返回写入的数据项的数目数据项数目并不等于实际写入的字节数除非参数 size 等于 1如果发生错误则 fwrite()返回的值将小于参数 nmemb或者等于 0。 3.6 fseek定位 #include stdio.h int fseek(FILE *stream, long offset, int whence); //用于设置文件读写位置偏移量。函数参数和返回值含义如下 stream FILE 指针。 offset 与 lseek()函数的 offset 参数意义相同。 whence 与 lseek()函数的 whence 参数意义相同。 返回值 成功返回 0发生错误将返回-1并且会设置 errno 以指示错误原因 与 lseek()函数的返回值 意义不同这里要注意#include stdio.h long ftell(FILE *stream); //用于获取文件当前的读写位置偏移量。 3.7 检测或复位状态 1.feof函数 用于测试参数 stream 所指文件的 end-of-file 标志。 #include stdio.h int feof(FILE *stream); 2.ferror函数 用于测试参数 stream 所指文件的错误标志。 #include stdio.h int ferror(FILE *stream); 3.clearerr函数 用于清除 end-of-file 标志和错误标志。 #include stdio.h void clearerr(FILE *stream); 3.8 格式化I/O 1.格式化输出 #include stdio.h int printf(const char *format, ...); //将程序中的字符串信息输出显示到终端int fprintf(FILE *stream, const char *format, ...); //将格式化数据写入到由 FILE 指针指定的文件中int dprintf(int fd, const char *format, ...); //将格式化数据写入到由文件描述符 fd 指定的文件中int sprintf(char *buf, const char *format, ...); //将格式化数据存储在由参数 buf 所指定的缓冲区中int snprintf(char *buf, size_t size, const char *format, ...); //与sprintf一样为了防止缓冲区溢出加入了参数size多出的将丢弃。 printf举例%[flags][width][.precision][length]typeflags 标志可包含 0 个或多个标志 width 输出最小宽度表示转换后输出字符串的最小宽度 precision 精度前面有一个点号 . length 长度修饰符 type 转换类型指定待转换数据的类型。type d/i:  into:    unsigned int无符号八进制u:    unsigned int无符号十进制x/X unsigned int无符号十六进制大小写f/F double浮点数默认保留小数后六位e/E double科学计数法表示浮点数g/G double根据数值的长度选择以最短的方式输出s   char *字符串p   void *十六进制表示的指针c   char字符型可以把输入的数字转换到 ASCII 码字符输出 flags #带前缀0在输出的数字前补0-左对齐‘ ’(空格)正数前面加空格负数前面加负号输出正数的正号 width 最小的输出宽度用十进制数来表示输出的最小位数若实际的输出位数大于指定的输出的最小位数则以实际的位数进行输出若实际的位数小于指定输出的最小位数则可按照指定的 flags 标志补 0 或补空格。 precision精度显示小数点后的位数。 length指明待转换数据的长度。 2.格式化输入 #include stdio.h int scanf(const char *format, ...); //将用户输入标准输入的数据进行格式化转换并进行存储int fscanf(FILE *stream, const char *format, ...); //从指定文件中读取数据作为格式转换的输入数据int sscanf(const char *str, const char *format, ...); //从参数 str 所指向的字符串缓冲区中读取数据作为格式转换的输入数据format %[*][width][length]type %[m][width][length]typewidth 最大字符宽度 length 长度修饰符与格式化输出函数的 format 参数中的 length 字段意义相同。 type 指定输入数据的类型。与printf一致。 3.9 I/O缓冲 1.文件I/O的内核缓冲 read()和 write()系统调用在进行文件读写操作的时候并不会直接访问磁盘设备而是仅仅在用户空间缓冲区和内核缓冲区kernel buffer cache之间复制数据。 2.刷新文件I/O的内核缓冲区 控制文件I/O内核缓冲的系统调用 #include unistd.hint fsync(int fd); //将参数 fd 所指文件的内容数据和元数据写入磁盘,写完之后返回int fdatasync(int fd); //与fsync类似只写入内容数据不写元数据(记录文件属性相关的数据信息比如文件大小、时间戳、权限等)void sync(void); //刷新所有文件 I/O 内核缓冲区 控制文件I/O内核缓冲的标志 fd open(filepath, O_WRONLY | O_DSYNC); //在每个 write()调用之后调用 fdatasync()函数进行数据同步fd open(filepath, O_WRONLY | O_SYNC); //在每个 write()调用之后调用 fsync()函数进行数据同步 对性能的影响 在程序中频繁调用 fsync()、 fdatasync()、 sync()或者调用 open 时指定 O_DSYNC 或 O_SYNC 标志对性能的影响极大大部分不会使用。   3.直接I/O绕过内核缓冲 Linux 允许应用程序在执行文件 I/O 操作时绕过内核缓冲区从用户空间直接将数据传递到文件或磁盘设备。 fd open(filepath, O_WRONLY | O_DIRECT); 直接 I/O 的对齐限制 ⚫ 应用程序中用于存放数据的缓冲区其内存起始地址必须以块大小的整数倍进行对齐 ⚫ 写文件时文件的位置偏移量必须是块大小的整数倍 ⚫ 写入到文件的数据大小必须是块大小的整数倍。 如何确定磁盘分区的块大小呢可以使用 tune2fs 命令进行查看 tune2fs -l /dev/sda1 | grep Block size 4.stdio缓冲 对 stdio 缓冲进行设置 #include stdio.hint setvbuf(FILE *stream, char *buf, int mode, size_t size); stream FILE 指针用于指定对应的文件。 buf指向 size 大小的内存区域将作为该文件的 stdio 缓冲区 mode 参数 mode 用于指定缓冲区的缓冲类型:_IONBF(不缓冲),_IOLBF(行缓冲),_IOFBF(全缓冲)。 size 指定缓冲区的大小。 返回值 成功返回 0失败将返回一个非 0 值并且会设置 errno 来指示错误原因。void setbuf(FILE *stream, char *buf); bufNULL无缓冲或者BUFSIZ字节的缓冲区void setbuffer(FILE *stream, char *buf, size_t size); //允许调用者指定 buf 缓冲区的大小 刷新stdio缓冲区 #include stdio.h int fflush(FILE *stream); //stream 指定需要进行强制刷新的文件如果该参数设置为 NULL则表示刷新所有的 stdio 缓冲区调用 fflush()库函数可强制刷新指定文件的 stdio 缓冲区 调用 fclose()关闭文件时会自动刷新文件的 stdio 缓冲区 程序退出时会自动刷新 stdio 缓冲区注意区分不同的情况return会刷新_exit和_Exit不会刷新 。 5.I/O缓冲小节 3.10 文件描述符和FILE指针互转 #include stdio.h int fileno(FILE *stream); FILE *fdopen(int fd, const char *mode);
http://www.w-s-a.com/news/374329/

相关文章:

  • app 与网站网站建设要做什么
  • 厦门国外网站建设公司郑州核酸点推vip服务
  • 免费网线seo外链怎么做
  • 宽带技术网网站wordpress widget hook
  • 山西省住房和城乡建设厅网站报名wordpress添加标签插件
  • 网站怎么自己做外贸网站案例
  • 做网站的优势公司网站怎么做站外链接
  • 海城网站制作建设精准营销的营销方式
  • 北京短视频拍摄公司重庆网站seo推广公司
  • 广州免费推广网站建设4399网页游戏大全
  • 网站的构架与组成建站公司兴田德润
  • php网站部署步骤邯郸哪有做网站的
  • 做设计什么设计比较好的网站南充市住房和城乡建设局考试网站
  • 郑州做系统集成的公司网站龙岩
  • 厦门SEO_厦门网站建设网络营销课程视频
  • vs 2015 网站开发开网店在线咨询
  • 前端如何优化网站性能大学学校类网站设计
  • 中国铁路建设投资公司网站熊学军中国it外包公司排名前50
  • 房产网站的建设广州推广排名
  • 湟源县网站建设wordpress删除未分类
  • 营销型网站开发推广厦门百度seo公司
  • 遵义网站开发培训上海中高风险地区名单最新
  • 禹州市门户网站建设做网站可以申请个体户么
  • 大良营销网站建设效果彩票网站搭建 做网站
  • 做网站的公司为什么人少了在中国如何推广外贸平台
  • 盘锦网站制作工业电商网站怎么配色
  • 白云企业网站建设seo排名点击软件
  • wordpress跨站脚本攻击漏洞国外注册的域名国内能用吗
  • 西部数码网站管理助手2工信部资质查询网站
  • 公司网站哪个建的好吉林网站制作