linux系统调用和用户编程接口(api)

系统调用是指在操作系统提供给用户程序调用的一组“特殊”的接口,用户程序可以通过这组特殊的接口来获取操作系统内核提供的服务,例如用户可以通过进程控制相关的系统调用来创建进程,实现进程调度,进程管理

为什么用户不能直接访问系统内核提供的服务?这是因为在linux中,为了更好地保护内核空间,将程序运行的空间分为内核空间和用户空间(也就是常称为的内核态和用户态)

内核态和用户态运行在不同的级别上,在逻辑上也是相互隔离的,新词用户进程在通常情况下是不允许范围内核数据,也无法使用内核的函数,他们只能在用户空间操作用户数据,调用用户空间的函数

但是,在有些情况下,用户空间的进程需要获得一定的系统服务,调用内核空间程序,这时操作系统就必须利用系统提供给用户的特殊接口,系统调用规定用户进程进入内核空间的具体位置,进行系统调用的时,程序从用户空间进入内核空间,处理完后在返回用户空间

linux系统调用部分是非常精简的系统调用(只有250)他继承了unix系统调用最基本和最有用的部分,这些系统调用按照功能和逻辑大致可以分为

进程控制,进程间通信,文件系统控制,系统控制,存储管理,网络管理,socket控制,用户管理

用户编程的api

前面讲到的系统调用便不是直接与程序员进行交互,它仅仅是一个软中断机制向内核提出请求,以获取内核服务的接口,在实际使用中,程序员调用的是用户编程对应的接口--api

linux中文件及文件描述符概述

在linux中对目录和设备的操作都等同于对文件的操作,因此大大简化了系统对不同设备的处理,linux中的文件主要分为4种,普通文件,目录文件,链接文件和设备文件,对于linux而言,所有对设备和文件的操作都是使用文件描述符来进行的

文件描述符是一个非负整数,他是一个索引值,并指向内核中每个进程打开文件的记录表,当打开一个现存文件,或者是创建一个新的文件时,内核就像进程返回一个文件描述符,但需要写入文件时,也需要吧文件描述符作为参数传递给相应的函数

通常一个进程启动时,都会打开三个文件,标准输入,标准输出,标准出错处理,对应文件描述符为0,1,2。

基于文件描述符的I/0操作虽然不能移植到类linux以外的系统上去(如windows)但它往往是实现某些I/0操作的唯一途径,基于文件描述符的I/O操作时linux中对常用的操作之一

底层文件I/O操作

这里主要是5个函数open(),read(),write(),lseek(),和close()这些函数的特点是不带缓存,直接对文件(包括设备)进行读写操作

open()函数用于打开或创建文件,在打开或创建文件时,可以指定文件的属性和用户的权限等各种参数。

close()是一个用于关闭一个被打开的文件。当一个进程终止时,所有被他打开的文件都由内核自动关闭,很多程序都使用这一功能而不显示的关闭一个文件

read()函数用于将从指定的文件描述符中读取数据放到缓存区,并返回实际读入的字节数,若返回0,则表示没有数据可读,即已经达到文件尾,读操作文件从文件的当前指针位置开始,当从终端设备文件中读取数据时,通常一次最多读取一行

write()函数用于向打开的文件中写入数据,写操作从文件的当前指针位置开始,对磁盘文件进行写操作,若磁盘已经写满,或者超出文件的长度,则write()函数返回失败

lseek()函数用于在指定的文件描述符中将文件的指针定位到相应的位置,它只能用在可定位(可随机访问)文件操作中,管道,套接字,和大部分字符设备文件是不可定位的,所以在这些文件的操作中无法使用lseek

open函数的原型 int open(const char *pathname ,int flags);pathname是指文件的路径名和名称,可以是绝对路径或者是相对路径,flag 是指定了文件的打开方式

O_RDONLY 以只读方式,要求文件存在

O_WRONLY以只写的方式打开,要求文件存在

O_RDWR可读可写的方式打开,要求文件存在

O_CREAT 创建文件

O_EXCL创建互斥

O_APPEND 以追加的方式写入首先要有写权限

O_TRUNC 清空原文件内容

返回值 为文件描述符,非负整数,文件后续操作的标志

open的另外一种原型为int open(const char *pathname,int flags,mode_t mode)前面的参数和一样,mode是指创建文件时的权限0x777 0x644 0x664等等

打开文件失败的原因分析:1文件不存在时指定可读,2文件所在目录无操作权限 3其他原因,文件操作权限,文件是否可用

close函数 函数原型为int close (int fd);

fd为open返回值的文件描述符,关闭文件后,该文件描述符将不可再用,返回值表示关闭是否成功,但我们编程时不处理该返回值,打开文件必须关闭,否则会造成文件描述符的泄漏,特别是异常情况,可以关闭0,1,2;

示例代码:

read 函数原型为 int read(int fd, void *buf,int count);fd为文件描述符(注意此处不能是文件名),buf为存储读取的内容的内存地址(指针),一定不能是野指针或者是空指针,count是本次读取的字节数,要求count要小于等于buf的大小,如果存储字符串时,返回值为成功读取的字节数,如果读取失败,返回小于0的值,返回值为0表示读取到文件末尾

示例代码:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h> int main(void)
{
int fd1,size;
char buf[]; fd1 = open("/etc/net/works",O_RDONLY);
if(fd1<)
{
printf("open fail\n");
exit();
}
while()
{
size = read(fd1,buf,);
if(size<)
{
printf("read error\n");
exit();
}
if(size ==)
break;
buf[size+] = '\0';
printf("%s",buf); }
close(fd1); return ;
}

memset用于在某段内存中填充那一个数,函数包含的头文件是#include<string.h>函数原型为

void *memset(void *s,int c,size_t n);例如memset(buf,0,,128);

注意 :read函数会自动对文件的操作位置进行偏移,读完几个字节,之后就偏移几个字节,自动偏移,如果到达文件末尾,不能再次偏移

如果读取失败的原因:

1文件的读取权限问题

2,文件没有内容,需要注意,如果使用O_TRUNC时,文件内容已经被清楚

3:如果该处出现段错误,这主要考虑内存指针是否为野指针或者是否越界

write函数;函数原型为 int write(int fd, void *buf,int count);

fd为写入的文件描述符,buf为需要写入的内容的指针,count是写入的字节数,这里的buf要小于buf的有效值,返回值为成功写入的字节数,返回值小于0表示写入失败

write也会对文件的操作位置进行偏移,如果为追加方式时,从文件的末尾开始写入,如果写入失败,如果写入失败,这分析原因为:1)文件是否有写权限,2)文件写入多错误时,可以查看内存是否越界,3)注意使用)O_TRUNC会清空原内容

#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h> int main(void)
{
int fd1,fd2,size,f3;
char buf[]; fd1 = open("/etc/xinetd.d/daytime",O_RDONLY);
if(fd1<)
{
printf("open fail\n");
exit();
} fd2 = open(""daytime1",O_RDWR|O_CREAT,777);
if(fd2<)
{
, Top
printf("create daytime1 fail\n");
exit();
} while()
{
memset(buf,,);
size = read(fd1,buf,); if(size<)
{
printf("read fail\n");
exit();
} if(size==)
break; buf[]='\0';
printf("%s",buf); f3 = write(fd2,buf,size);
if(f3<)
{
printf("write fail\n");
exit();
} } close(fd1);
close(fd2); return ;
}

版权所有,转载请注明转载地址:http://www.cnblogs.com/fengdashen/p/3300614.html

文件I/O操作(1)的更多相关文章

  1. 用 JSP 实现对文件的相关操作

    前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...

  2. PHP文件相关的操作函数——目录操作

    1.有关文件类型的函数 PHP是以UNIX的文件系统为模型的,因此在Windows系统中我们只能获得“file”.“dir”或者“unknown”三种文件类型.而在UNIX系统中,我们可以获得“blo ...

  3. C#对文件/目录的操作:Path、File、Directory、FileStream、StreamReader、StreamWriter等类的浅析

    以下类的命名空间都是:System.I/0; 一.Path:主要对文件路径的操作! 常用方法: String path=@"C:\a\b\c\123.txt"; 1-1.Path. ...

  4. 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法

    无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法   问题描述: 在附加数据库到sql server时,附 ...

  5. java io流 对文件夹的操作

    java io流 对文件夹的操作 检查文件夹是否存在 显示文件夹下面的文件 ....更多方法参考 http://www.cnblogs.com/phpyangbo/p/5965781.html ,与文 ...

  6. php对xml文件进行CURD操作

    XML是一种数据存储.交换.表达的标准: - 存储:优势在于半结构化,可以自定义schema,相比关系型二维表,不用遵循第一范式(可以有嵌套关系): - 交换:可以通过schema实现异构数据集成: ...

  7. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  8. Python::OS 模块 -- 文件和目录操作

    os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...

  9. INI 文件的读写操作

    在C#中对INI文件进行读写操作,在此要引入using System.Runtime.InteropServices; 命名空间,具体方法如下: #region 变量 private static r ...

  10. Android 对 properties文件的读写操作

    -. 放在res中的properties文件的读取,例如对放在assets目录中的setting.properties的读取:PS:之所以这里只是有读取操作,而没有写的操作,是因为我发现不能对res下 ...

随机推荐

  1. mysql.zip免安装版配置

    MYSQL ZIP免安装版配置 1. 下载MySQL 选择自己想要的.本次安装.我使用的是mysql-5.6.17-winx64  地址:http://dev.mysql.com/downloads/ ...

  2. 4.4 spring-自定义标签的解析

    1.0 自定义标签的解析. 在之前的章节中,我们完成了对spring 默认标签的加载过程.那么现在我们将开始新的里程, spring 自定义标签的解析; 代码如下: /** * Parse the e ...

  3. SQL 聚集函数使用

    SQL 聚集函数使用 (2009-04-14 15:50:36) 转载▼   总结: 在SQL语句中同时包含where子句,groupby子句,having子句及聚集函数时的执行顺序: 1.按WHER ...

  4. API HOOK

    API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...

  5. Discuz云平台站点信息同步失败,An unknown error occurred. May be DNS Error.

    站点信息同步失败 An unknown error occurred. May be DNS Error. (ERRCODE:1) 经过Discuz教程网(http://www.1314study.c ...

  6. 【NGUI】屏幕自适应(不用UIStretch,用UIRoot)---------------good

    原地址:http://blog.csdn.net/lzhq1982/article/details/18814023 这篇文章是转载的,之前用UIStretch做屏幕自适应,但一直有两个硬伤让我难受, ...

  7. valgrind基本使用

    1.valgrind是一个内存检测工具,类似的还有purify,insure++等 2.测试文件test.c test.c : main(){ int* a=new int[100]; return ...

  8. nginx面试题

    1.Nginx是如何实现高并发的 service nginx start之后,然后输入#ps -ef|grep nginx,会发现Nginx有一个master进程和若干个worker进程,这些work ...

  9. libevent安装

    libevent : 名气最大,应用最广泛,历史悠久的跨平台事件库:libev : 较libevent而言,设计更简练,性能更好,但对Windows支持不够好:libuv : 开发node的过程中需要 ...

  10. java文档注释主要使用方法

    一.java包含哪些注释 1.//用于单行注释. 2./*...*/用于多行注释,从/*开始,到*/结束,不能嵌套. 3./**...*/则是为支持jdk工具javadoc.exe而特有的注释语句.这 ...