二、linux IO 编程---系统调用和POSIX标准和标准IO

时间:2022-09-07 08:04:50

2.1 系统调用

2.1.1 概念

  所谓系统调用(system call)是指曹错系统提供给用户程序的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的特殊服务。

  二、linux IO 编程---系统调用和POSIX标准和标准IO

  • 应用程序可以直接调用系统调用获得内核的服务
  • shell 可以调用系统调用
  • 标准C库,也可以调用系统调用,获得内核服务  

2.1.2 linux 进程的运行状态

  当应用程序进行系统调用的时候,进程运行状态会发生变化,进程会从运行态变为内核态,当调用完成后,则从内核态变为运行态。

  • 内核态:进程运行在内核空间
  • 运行态:进程运行在用户空间

2.2 UNIX 标准

  • ISO C
  • IEEE POSIX
    • 在 linxu 中用户编程接口(API)遵循了在 UNIX 中最流行的应用编程界面标准——POSIX 标准。这些系统调用编程接口主要通过C库(libc)实现的。

2.3 标准IO

  文件操作标准I/O库函数:

  fopen、fread、fwrite、fclose、fflush、fseek、fgetc、getc、getchar、fputc、putc、putchar、fgets、gets、printf、fprintf、sprintf、scanf、fscanf、sscanf、fgetops、fsetops、ftell、rewind、freopen、setvbuf、remove、fileno、fdopen

  目录操作标准I/O库函数:

  opendir、readdir、telldir、seekdir、closedir

2.3.1  fopen -- 用于打开一个文件,返回一个指向该文件的文件指针

 #include<stdio.h>
FILE *fopen(const char *filename, const char *mode);

参数说明:
  filename -- 指定了被打开的文件的路径(相对路径或绝对路径)
  mode -- 指定了被打开文件的操作方式,如下:
    "r"    --  只读
    "w"   --  只写,并将文件截断为0
    "a"    --  只写,以追加方式从文件尾开始写
    "r+"      --  读写
    "w+"    --   读写,并将文件截断为0
    "a+"     --  读写,以追加方式从文件尾开始写
fopen执行成功时返回指向被打开文件的文件流指针,失败时返回NULL。

2.3.2 fread -- 用于从一个文件流中读取数据

#include<stdio.h>
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);

参数说明:
  ptr       --   指定从文件流中读取的数据所存放的地方
  size      --   指定所读取的每一条记录的大小,单位字节
  items    --   指定本次读操作所读取的记录条数
  stream  --   指定读取数据的来源————文件流
fread执行成功时返回实际读取记录的条数。

2.3.3 fwrite -- 用于写数据到一个文件流中

#include<stdio.h>
size_t fwrite(void *ptr, size_t size, size_t nitems, FILE *stream);

参数的含义以及返回的结果类似于fread。需要说明的是,fread和fwrite并不适合从结构化的数据源中读取数据,一个主要原因是fwrite可移植性较差。

2.3.4 fclose -- 断开一个文件流指针与文件的关联

#include<stdio.h>
int fclose(FILE *stream);

fclose操作将会引起所要关闭的文件流刷新缓冲区的操作,这使得该文件流上的所有读写操作都立刻执行。当程序正常终止时会对所有尚未关闭的文件流自动执行fclose操作。

2.3.5 fflush -- 刷新指定文件流的缓冲区

#include<stdio.h>
int fflush(FILE *stream);

fflush函数会使得文件流上所有未执行写操作立刻执行,这在交互性的程序中特别有用。在调用fclose函数关闭一个文件流时,实际上隐含调用了一次fflush操作。

2.3.6 fgetc、getc、getchar -- 从指定文件流中读取一个字节的数据

#include<stdio.h>
int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar();

函数fgetc从指定的文件流中读取一个字节的数据,并返回该字节数据的整型值,当读到文件尾或发生错误时返回EOF。getc同fgetc,只是它有可能被实现为宏。getchar函数相当于从标准输入读取字节时的fgetc。

2.3.7 fputc、putc、putchar -- 写一个字节数据到指定的文件流

#include<stdio.h>
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);

fputc函数将一个字节写到指定的文件流中,成功时返回返回写入的字节的整型值,失败时返回EOF。putc同fputc,只是有可能被实现为宏。putchar相当于向标准输出写一个字节时的fputc。

2.3.8 fgets、gets -- 用于从一个文件流读取一个字符串

#include<stdio.h>
char *fgets(char *s, int n, FILE *stream);
char *gets(char *s);

参数说明:
  s -- 指定存放所读取的数据的位置
  n -- 指定读取数据的最大长度(包括结尾的\0字符)
  stream -- 数据源,是一个文件指针
fgets函数从指定的文件流指针中读取一个字符串,直到遇到换行符或者已经读了n-1个字符或者遇到文件EOF,它会在所读取的数据结尾加上一个\0字符,然后放到s指定的位置。成功时返回返回指向s的指针,失败时返回NULL,并重置全局变量errno以指明失败原因。读到文件尾EOF时也返回NULL。
gets函数从标准输入流中读取一个字符串,直到遇到换行符(它会把换行符扔掉并不上一个\0字符)后返回。处于安全的考虑,建议使用fgets函数。

2.3.9 printf、fprintf、sprintf -- 格式化输出函数

#include<stdio.h>
int printf(const char *format, ...);
int sprintf(char *s, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);

参数说明:
  format -- 格式字符串,它可以分为两个部分:普通字符和转换说明。普通字符原样输出,转换说明用于指定printf系列函数的输出格式,它以百分号开始,以转换字符结束,具体如下:

printf格式说明
 转换说明  输出结果
 %d,%i  输出十进制整型
 %o  输出八进制整型
 %x  输出十六进制整型
 %u  输出无符号十进制整型
 %c  输出一个字符
 %s  输出一个字符串
 %f  输出一个单精度浮点数
 %e,%E  输出一个双精度浮点数,以科学计数法的形式表示
 %g,%G  以一般格式输出一个双精度浮点数
 %p  void *类型指针(取决于具体实现)
 %%  输出一个百分号

  其中d、i、o、x、X、u、……、p就是转换字符,在百分号与转换字符之间可能依次包含下列组成部分:

  • 负号     --    指定被转换的参数按照左对齐形式输出,默认为右对齐
  • 整数     --    用于指定最小字段宽度,如有必要将以空格填充以保证对齐
  • 小数点  --    用于将字段宽度与字段精度分开
  • 整数     --    用于指定精度,即字符串中要打印的最大字符数、浮点数小数点后的位数、整数最少输出的数字数目
  • 字母     --    如h用来指定打印short类型,l用来指定打印long类型

2.3.10 scanf、fscanf、sscanf -- 格式化输入函数

#include<stdio.h>
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(char *s, const char *format, ...);

scanf系列函数的参数的作用与printf系列函数参数的作用方式十分不同,在scanf系列函数中,输入(获取变量值的源)与格式字符串之间是一种匹配的关系,只有二者匹配成功,scanf函数才有可能执行成功。比如对于scanf("Hello %d", &i)而言,它要求输入中必须以Hello单词为前导,否则将匹配失败,scanf函数就不能成功执行。格式串可能包含的部分如下:

  • 空格或制表符    --  在处理过程中将被忽略,不用于匹配
  • 普通字符        --  用于匹配输入流中的下一个非空白字符
  • 转换说明        --  依次由一个%、一个可选赋值禁止字符*、一个可选数值(指定最大字段宽度)、一个可选h或l或L字符(指定目标对象的宽度)以及一个转换字符组成

转换说明用于控制下一个输入字段的转换。通常,转换结果存放在相应的参数指向的变量中,但是如果转换说明中包含赋值禁止字符*,则跳过该输入字段,不进行赋值。输入字段定义为一个不包含空白字符的字符串,因此其边界就定义为下一个空白字符(或者到达指定的宽度)。转换字符指定对输入字段的解释,对应的参数必须是指针,scanf转换字符的解释同printf的转换字符。

2.3.11 其它不常用的标准输入输出库函数

#include<stdio.h>
int fgetpos(FILE *stream, fpos_t *pos); /* 得到当前读写位置 */
int fsetpos(FILE *stream, const fpos_t *pos); /* 设置当前读写位置 */
long int ftell(FILE *stream); /* 返回当前读写位置的偏移量 */
void rewind(FILE *stream); /* 重置文件流的读写位置 */
FILE *freopen(const char *filename, const char *mode, FILE *stream); /* 复用一个文件流指针 */

2.3.12、opendir -- 打开一个目录

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

成功时返回指向一个目录的目录指针,失败时返回NULL。

2.3.13、readdir -- 读取一个目录的目录项

#include<sys/types.h>
#include<dirent.h>
struct dirent *readdir(DIR *dirp);

成功时返回一个指向struct dirent结构(它被用来保存目录项)的指针,失败或者到达目录目录结尾(最后一项之后)时返回NULL。struct dirent结构至少包含以下两个元素:

ino_t d_ino;    /* 文件的indoe节点号 */
char d_name[]; /* 文件名 */

2.3.14、telldir -- 返回目录流但前的读写位置

#include<sys/types.h>
#include<dirent.h>
long int telldir(DIR *dirp);

2.3.15、seekdir -- 用于设置目录流中指向目录项的指针的指向的位置

#include<sys/types.h>
#include<dirent.h>
void seekdir(DIR *dirp, long int loc);

结合telldir函数,可以让目录流回到之前的读写位置。

2.3.16、closedir -- 断开一个目录流指针与一个目录的关联

#include<sys/types.h>
#include<dirent.h>
int closedir(DIR *dirp);

成功时返回0,失败时返回1并设置全局变量errno的值。

2.3.17、strerror -- 错误处理

#include<string.h>
char *strerror(int errnum);

这个函数接受一个整型值(通常在I/O错误发生时,用errno值作为参数的值),返回一个指向该整型值所代表的错误信息的字符串的指针。

2.3.18、perror -- 输出错误信息到标准错误

#include<stdio.h>
void perror(const char *s);

该函数会报告全局变量errno所代表的错误到,输出格式如下:
  s: errstr
前面s表示传给perror函数的参数(字符串),然后跟上一个冒号和一个空格,后面是当前出错信息。

2.4 FILE 结构体

  头文件 stdio.h,以下只是简单的参数,还有很多参数

  二、linux IO 编程---系统调用和POSIX标准和标准IO

  fd 文件描述符就是联系的标准IO和系统调用IO的。

  标准C的IO 都是带缓存的。调用标准C,写入或读取数据时候,先读写到缓存中,然后才输入或输出到定义的变量 buf 或 文件中。

  缓存操作如下:

  二、linux IO 编程---系统调用和POSIX标准和标准IO

  缓存遇到换行符或是return 或者写满缓存后的时候,才会输出。

  数据先写进缓存,然后再输出到文件或屏幕上。

  stdin:标准输入,scanf 类函数就是默认的使用此函数

  stdout:标准输出,printf 函数默认使用此

  stderr:标注错误

  这三个就是FILE 类型结构体指针,也称为流指针

2.5 标准C的缓存类型

  • 全缓存:要求填满整个缓存区后才进行 I/O 系统调用。对于磁盘文件通常使用全缓存访问
    • 还有一种就是通过 fflush 函数将缓存输出出来
    • 程序结束时候也会自动输出,此时会自动调用   fflush 函数  
  • 行缓存:涉及一个终端时(例如标准输入和标准输出),使用行缓存
    • 行缓存存满自动输出
    • 碰到换行符时也自动输出 
  • 无缓存:标准错误流 stderr 通常是不带缓存区的,这使得错误信息能够尽快的显示出来  

    

二、linux IO 编程---系统调用和POSIX标准和标准IO的更多相关文章

  1. linux文件锁的应用,POSIX,unix标准,linux标准

    1. perl,flock加锁.java也能加锁. 2. 先创建文件并打开,才能加锁(写打开?). 3. 可以用于判断进程是否一直在运行(用另一进程判断),如果锁一直在,则进程在:锁不在,则原进程或意 ...

  2. linux socket编程系统调用栈

    目录 一.网络协议参考模型简介 二.SOCKET概述 三.SOCKET基本数据结构 1.TCP通信编程 2.服务器端实例代码 3.客户端实例代码 4.头文件socketwrapper.h 5.程序实现 ...

  3. linux文件编程----系统调用

    linux中文件编程可以使用两种方法: 1).linux系统调用 2).C语言库函数 前者依赖于linux系统,后者与操作系统是独立的. 在 linux系统中,所有打开的文件也对应一个数字,这个数字由 ...

  4. Linux网络编程入门 &lpar;转载&rpar;

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  5. &lbrack;转&rsqb; - Linux网络编程 -- 网络知识介绍

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  6. 【转】Linux网络编程入门

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  7. 《转》Linux网络编程入门

    原地址:http://www.cnblogs.com/duzouzhe/archive/2009/06/19/1506699.html (一)Linux网络编程--网络知识介绍 Linux网络编程-- ...

  8. Linux网络编程入门

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户 ...

  9. linux网络编程&lowbar;1

    本文属于转载,稍有改动,以利于学习. (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个 ...

随机推荐

  1. CRM 2013 相关下载 &sol; 2013-10-11

        CRM 2013的安装文件,软件开发工具包(Sdk)以及实施指南,在微软官方网站已经有下载了.     具体地址如下: Name Url 发布日期 语言版本 说明 CRM Server htt ...

  2. &lbrack;课程设计&rsqb;Scrum 1&period;3 多鱼点餐系统开发进度(系统主界面框架&amp&semi;美化)

    Scrum 1.3 多鱼点餐系统开发进度(系统主界面框架&美化) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队选题:餐厅 ...

  3. JS-003-innerText 与 innerHTML 区别

    此文主要讲述在使用 innerText 和 innerHTML 获取元素中间值时的差别,我个人将二者的区别简单的理解为: webelement.innerText : 获取的是页面元素显示的文本 we ...

  4. jdbc事务

    买书的例子 程序应该将图书数量的操作和更新account用户余额的操作作为一个事务来处理,只有这两个操作都完成的情况下,才能提交事务,否则就回滚事务. 本文转自http://blog.chinauni ...

  5. Java 之 网络编程

    1.OSI模型 a.全称:开放系统互联 b.七层模型:应用层.表示层.会话层.传输层.网络层.数据链路层.物理层 c.注意:OSI模型 是所谓的 理论标准 2.TCP/IP模型 a.四层模型:应用层. ...

  6. SELinux开关导致mysql服务启动不了

    http://www.jb51.net/article/36187.htm 网站突然连接不上数据库,于是朋友直接重启了一下服务器.进到cli模式下,执行 service myqsld start 发现 ...

  7. C&num;编程实践–产假方案优化版

    前言 既然作为一个踏踏实实学习技术的人,就要有一颗谦卑.虚心和追求卓越的心,我不能一次就写出很完美的代码,但我相信,踏踏实实一步一步的优化,代码就可以变得趋近完美,至少在某一个特定场景下相对完美,这和 ...

  8. 深度学习实践系列(1)- 从零搭建notMNIST逻辑回归模型

    MNIST 被喻为深度学习中的Hello World示例,由Yann LeCun等大神组织收集的一个手写数字的数据集,有60000个训练集和10000个验证集,是个非常适合初学者入门的训练集.这个网站 ...

  9. mysql视图详解 mysql视图

    目录 22.1. ALTER VIEW语法 22.2. CREATE VIEW语法 22.3. DROP VIEW语法 22.4. SHOW CREATE VIEW语法 本章讨论了下述主题: ·    ...

  10. Water Buying

    Water Buying time limit per test 1 second memory limit per test 256 megabytes input standard input o ...