Linux 下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions)。系统调用实际上就是指最底层的一个调用,在 linux 程序设计里面就是底层 调用的意思。面向的是硬件。而库函数调用则面向的是应用开发的,相当于应用程序的 api, 采用这样的方式有很多种原因,
第一:双缓冲技术的实现。第二,可移植性。第三,底层调用本身的一些性能方面的缺陷。

第四:让 api 也可以有了级别和专门的工作面向。

1、系统调用

系统调用提供的函数如 open, close, read, write, ioctl 等,需包含头文件 unistd.h。以 write 为例:其函数原型为 size_t write(int fd, const void *buf, size_t nbytes),其
操作对象为文件描述符或文件句柄 fd(file descriptor),要想写一个文件,必须先以可写权 限用 open 系统调用打开一个文件,获得所打开文件的 fd,例如 fd=open("/dev/video",
O_RDWR)。fd 是一个整型值,每新打开一个文件,所获得的 fd 为当前最大 fd 加 1。Linux 系统默认分配了 3 个文件描述符值:0-standard input,1-standard output,2- standard error。

系统调用通常用于底层文件访问(low-level file access),例如在驱动程序中对设备文件 的直接访问。

系统调用是操作系统相关的,因此一般没有跨操作系统的可移植性。

系统调用发生在内核空间,因此如果在用户空间的一般应用程序中使用系统调用来进行文件 操作,会有用户空间到内核空间切换的开销。

事实上,即使在用户空间使用库函数来对文件 进行操作,因为文件总是存在于存储介质上,因此不管是读写操作,都是对硬件(存储器) 的操作,都必然会引起系统调用。也就是说,库函数对文件的操作实际上是通过系统调用来 实现的。例如 C 库函数 fwrite()就是通过 write()系统调用来实现的。

这样的话,使用库函数也有系统调用的开销,为什么不直接使用系统调用呢?这是因为,读 写文件通常是大量的数据(这种大量是相对于底层驱动的系统调用所实现的数据操作单位而 言),这时,使用库函数就可以大大减少系统调用的次数。

这一结果又缘于缓冲区技术。在 用户空间和内核空间,对文件操作都使用了缓冲区,例如用 fwrite 写文件,都是先将内容 写到用户空间缓冲区,当用户空间缓冲区满或者写操作结束时,才将用户缓冲区的内容写到 内核缓冲区,同样的道理,当内核缓冲区满或写结束时才将内核缓冲区内容写到文件对应的 硬件媒介。

2、库函数调用

标准 C 库函数提供的文件操作函数如 fopen, fread, fwrite, fclose, fflush, fseek 等,需包含头文件 stdio.h。

以 fwrite 为例,其函数原型为 size_t fwrite(const void buffer, size_t size, size_t item_num, FILE pf),其操作对象为文件指针 FILE *pf,要想写一个文件,必须先以可写权限用 fopen 函数打开一个文件,获得所打开文件的 FILE 结构指针 pf,例如 pf=fopen("~/proj/filename", "w")。

实际上,由于库函数对文件的操作最终是通过系统调用实现的,因此,每打开一个文件所获 得的 FILE 结构指针都有一个内核空间的文件描述符 fd 与之对应。同样有相应的预定义的 FILE 指针:stdin-standard input,stdout-standard output,stderr-standard error。

库函数调用通常用于应用程序中对一般文件的访问。

库函数调用是系统无关的,因此可移植性好。

由于库函数调用是基于 C 库的,因此也就不可能用于内核空间的驱动程序中对设备的操作。

[Linux C]系统调用(system call)和库函数调用(Library functions)的更多相关文章

  1. linux内核系统调用和标准C库函数的关系分析

    http://blog.csdn.net/skyflying2012/article/details/10044343

  2. Linux系统调用和库函数调用的区别

    Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思 ...

  3. linux系统调用和库函数调用的区别(转)

    Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions).可以参考<Linux程序设计>(英文原版为<Beginning ...

  4. [转载]Linux下关于system调用

    曾经的曾经,被system()函数折磨过,之所以这样,是因为对system()函数了解不够深入.只是简单的知道用这个函数执行一个系统命令,这远远不够,它的返回值.它所执行命令的返回值以及命令执行失败原 ...

  5. Linux 下系统调用的三种方法

    系统调用(System Call)是操作系统为在用户态运行的进程与硬件设备(如CPU.磁盘.打印机等)进行交互提供的一组接口.当用户进程需要发生系统调用时,CPU 通过软中断切换到内核态开始执行内核系 ...

  6. Linux添加系统调用的两种方法

    前言 系统调用的基本原理 系统调用其实就是函数调用,只不过调用的是内核态的函数,但是我们知道,用户态是不能随意调用内核态的函数的,所以采用软中断的方式从用户态陷入到内核态.在内核中通过软中断0X80, ...

  7. 系统调用system call以及strace/dtruss

    计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,进程是不允许直接操作这些资源的,所有对这些资源的访问都必须有操作系统控制.也就是说操作系统是使用这些资源的 ...

  8. 深入理解Linux的系统调用【转】

    一. 什么是系统调用 在Linux的世界里,我们经常会遇到系统调用这一术语,所谓系统调用,就是内核提供的.功能十分强大的一系列的函数.这些系统调用是在内核中实现的,再通过一定的方式把系统调用给用户,一 ...

  9. 【原创】Linux 增加系统调用

    Linux 增加系统调用大致步骤: 1.下载好内核文件,在内核源文件中添加好自己的调用函数. 2.编译内核 3.验证. 一.在内核源文件中增加自己的函数   首先将内核文件移至/usr/src/下并解 ...

随机推荐

  1. Linux的环境中如何生成srw-rw---- 的文件权限?

    文件属性 d 开头是: 目录文件. l 开头是: 符号链接(指向另一个文件,类似于瘟下的快捷方式). s 开头是: 套接字文件(sock). b 开头是: 块设备文件,二进制文件. c 开头是: 字符 ...

  2. mongoDB authentication

    转自:http://blog.csdn.net/allen_jinjie/article/details/9235073 1. 最开始的时候,我们启动mongodb,但是不包含--auth参数: E: ...

  3. NOIP2016 DAY2 T1 组合数问题

    题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...

  4. ORA-12560: TNS: 协议适配器错误(oracle service 已启动)

    如果是安装完 oracle 客户端之后才出现的这个问题,请往下看 安装 oracle client 时,会配置一个客户端的监听,如果电脑上之前安装过 oracle service 就会和服务的监听冲突 ...

  5. (0)前言【从零开始学Spring Boot】

    在此对整体技术简单说明下. 开发工具和开发环境: Win7 64位操作 Eclipse-jee-mars-2-win32-x86_64 Jdk 1.8 Maven管理项目 如果要学习Spring Bo ...

  6. js日期原型扩展

    当初做统计业务需要处理时间 周报:本周 上周 下周 近一周 月报上月 本月 等 需要使用时间处理 所以扩展了这些方法 <!DOCTYPE html> <html xmlns=&quo ...

  7. 大菲波数 【杭电-HDOJ-1715】 附题+具体解释

    /* 大菲波数 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. HDU 2045不easy系列之三LELE的RPG难题(趋向于DP的递推)

    不easy系列之(3)-- LELE的RPG难题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...

  9. JavaScript 获取小数任一小数点后的位数的小数

    用Javascript取float型小数点后两位,例22.127456取成22.13,怎样做? 1.这样的方法最不推荐: function get(){ var s = 22.127456 + &qu ...

  10. CSS初步理解

    近期在学习牛腩的时候遇到了网页的制作.挺新奇的.其中涉及到了有关CSS的知识,于是乎自己也就花费两个小时的时间.找了本浅显易懂的书来看了一遍,从宏观上来了解CSS的相关内容.有关CSS的基础知识详见下 ...