文件I/O操作(1)
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)的更多相关文章
- 用 JSP 实现对文件的相关操作
前段时间一直忙着作业,实验,动手的时间真是少之又少,今天终于可以继续和大家分享关于 JSP 的学习心得. 简单总结一下吧: JSP 理论性很强,感觉就是纯语法. 我更偏向于实际编写代码,这样更容易理解 ...
- PHP文件相关的操作函数——目录操作
1.有关文件类型的函数 PHP是以UNIX的文件系统为模型的,因此在Windows系统中我们只能获得“file”.“dir”或者“unknown”三种文件类型.而在UNIX系统中,我们可以获得“blo ...
- C#对文件/目录的操作:Path、File、Directory、FileStream、StreamReader、StreamWriter等类的浅析
以下类的命名空间都是:System.I/0; 一.Path:主要对文件路径的操作! 常用方法: String path=@"C:\a\b\c\123.txt"; 1-1.Path. ...
- 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法
无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问.)” (Microsoft SQL Server,错误: 5120)的解决方法 问题描述: 在附加数据库到sql server时,附 ...
- java io流 对文件夹的操作
java io流 对文件夹的操作 检查文件夹是否存在 显示文件夹下面的文件 ....更多方法参考 http://www.cnblogs.com/phpyangbo/p/5965781.html ,与文 ...
- php对xml文件进行CURD操作
XML是一种数据存储.交换.表达的标准: - 存储:优势在于半结构化,可以自定义schema,相比关系型二维表,不用遵循第一范式(可以有嵌套关系): - 交换:可以通过schema实现异构数据集成: ...
- 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】
一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...
- Python::OS 模块 -- 文件和目录操作
os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...
- INI 文件的读写操作
在C#中对INI文件进行读写操作,在此要引入using System.Runtime.InteropServices; 命名空间,具体方法如下: #region 变量 private static r ...
- Android 对 properties文件的读写操作
-. 放在res中的properties文件的读取,例如对放在assets目录中的setting.properties的读取:PS:之所以这里只是有读取操作,而没有写的操作,是因为我发现不能对res下 ...
随机推荐
- mysql.zip免安装版配置
MYSQL ZIP免安装版配置 1. 下载MySQL 选择自己想要的.本次安装.我使用的是mysql-5.6.17-winx64 地址:http://dev.mysql.com/downloads/ ...
- 4.4 spring-自定义标签的解析
1.0 自定义标签的解析. 在之前的章节中,我们完成了对spring 默认标签的加载过程.那么现在我们将开始新的里程, spring 自定义标签的解析; 代码如下: /** * Parse the e ...
- SQL 聚集函数使用
SQL 聚集函数使用 (2009-04-14 15:50:36) 转载▼ 总结: 在SQL语句中同时包含where子句,groupby子句,having子句及聚集函数时的执行顺序: 1.按WHER ...
- API HOOK
API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...
- Discuz云平台站点信息同步失败,An unknown error occurred. May be DNS Error.
站点信息同步失败 An unknown error occurred. May be DNS Error. (ERRCODE:1) 经过Discuz教程网(http://www.1314study.c ...
- 【NGUI】屏幕自适应(不用UIStretch,用UIRoot)---------------good
原地址:http://blog.csdn.net/lzhq1982/article/details/18814023 这篇文章是转载的,之前用UIStretch做屏幕自适应,但一直有两个硬伤让我难受, ...
- valgrind基本使用
1.valgrind是一个内存检测工具,类似的还有purify,insure++等 2.测试文件test.c test.c : main(){ int* a=new int[100]; return ...
- nginx面试题
1.Nginx是如何实现高并发的 service nginx start之后,然后输入#ps -ef|grep nginx,会发现Nginx有一个master进程和若干个worker进程,这些work ...
- libevent安装
libevent : 名气最大,应用最广泛,历史悠久的跨平台事件库:libev : 较libevent而言,设计更简练,性能更好,但对Windows支持不够好:libuv : 开发node的过程中需要 ...
- java文档注释主要使用方法
一.java包含哪些注释 1.//用于单行注释. 2./*...*/用于多行注释,从/*开始,到*/结束,不能嵌套. 3./**...*/则是为支持jdk工具javadoc.exe而特有的注释语句.这 ...