Linux的文件I/O编程(系统函数)

系统调用和API
在Linux系统中,为了保护内核空间,将程序的运行空间,分为内存空间用户空间(内核态和用户态)它们在运行在不同的级别上,在逻辑上是相互隔离的,因此用户进程在通常情况下不允许访问内核数据,也无法使用内核函数,它们只能在用户空间操作用户数据和用户函数。操作系统为用户提供了两个接口:一个是用户编程接口API,用户利用这些操作命令来组织和控制任务的执行或管理计算机系统;另一个是系统调用,编程人员使用系统调用来请求操作系统提供服务。
系统调用并不是直接与程序员进行交互的,它仅仅是一个通过软中断机制向内核提交请求,以获得内核服务的接口。进行系统调用时,程序运行空间从用户空间进入内核空间,处理后再返回到用户空间。Linux系统调用部分,是非常精简的系统调用(只有250个左右),继承了Unix系统调用最基础的部分:进程控制、系统控制、内存管理、网络管理、socket控制、用户管理和进程间通信8个模块。

在这里插入图片描述
在Linux中,用户编程接口(API)遵循了Unix中最流行的应用编程界面标准POSIX标准。这些系统调用编程接口主要是通过c库(libc)来实现的。

对于Linux来说,所有文件和设备(设备也是文件)的操作,都使用文件描述符来进行。文件描述符是一个非负的整数,它是一个索引值,指向内核里每一个进程打开文件的记录表。当打开一个文件或者创建一个新文件,内核就会返回一个文件描述符,作为这个文件在用户空间的代表和唯一标识,读写函数等需要使用它。
通常,一个进程启动时,都会打开3个文件:标准输入、标准输出和标准出错处理。这三个文件对应的文件描述符为0、1、2 (即宏替换STDIN_FILENO、STDOUT_FILENO、STDERROR_FILENO)。使用这些宏替换,便于程序的理解和规范。

基本I/O操作:
Linux系统的读写函数,是不带缓冲区的读写操作。它们不属于ANSIC C的一部分,而是Unix的POSIX的一部分。

相关函数:

#include<sys/types.h>
#include<sys/stat.h>    //声明mode_t 
#include<fcntl.h>       //声明调用open()时使用的flag常量 
#include<unistd.h>      //声明ssize_t

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
size_t write(int fd,const void *buf, size_t count);
size_t write(int fd,const void *buf, size_t count);
off_t lseek(int fd, off_t offset, int whence);
int close(int fd);

open函数:
pathname:文件名,相对绝对都可以
flags:为一个或多个标识,表示文件打开方式。
mode:文件的存取权限模式,同文件属性权限那个的8进制表达。当打开已有文件时,将忽略这个参数。
返回值:文件描述符,失败返回 -1
flags表如下:
在这里插入图片描述
只需要写/读的话,就只写/只读,也可以文件专用,每个文件只负责一个特定的用途,有利于提高文件的重复利用。

read和write函数:
fd:文件描述符
buf:也是内存的一个地区。read则是指定文本流目的地,write则是文本流来源地
count:指定读写的字节数
返回值:错误的话,返回 -1.正确的话,返回实际的读写字节数。

lseek函数(光标位置偏移函数):
fd:文件描述符
offset :偏移量,多少个字节
whence:从哪里开始偏移,有有以下可选:
——SEEK_SET 偏移量设置为offset字节。(这一个最有用吧)
——SEEK_CUR 偏移量设置为当前位置加上offset字节。
——SEEK_END 偏移量设置为文件大小加上偏移字节大小。
返回值: 成功,lseek()返回的结果是从文件开头的字节偏移位置。否则,返回-1并设置errno以指示错误。

close函数:
fd:文件描述符
返回值:成功返回0,否则返回 -1.

程序:

#include<sys/types.h>
#include<sys/stat.h>    //声明mode_t 
#include<fcntl.h>       //声明调用open()时使用的flag常量 
#include<unistd.h>      //声明ssize_t
#include<stdio.h>
/*****
功能设计:
open一个不存在的文件,写入,再换一个绝对路径的文件  lseek函数要使用 
读取,最后关闭 

绝对、相对地址都可以写
append失败了 
用char [] 最佳 
*****/ 

int main()
{
	int FileDesc = 0;
	int Flag = 0;
	//又可以测试了
	// char * BufftoWrite = "this is a BufftoWrite\n";
	char BufftoWrite[] = "this is a BufftoWrite\n";
	char BuffertoRead[120];
	//第三个参数需不需要加,待测试 
	
	
	//写阶段 
	
	//可以写到其他地址那里去 
	//FileDesc = open("/mnt/hgfs/2440/tem.txt",O_WRONLY|O_CREAT,00777);
	//失败了,append不知道怎么搞 
	//FileDesc = open("/mnt/hgfs/2440/tem.txt",O_APPEND,00001);
	
	FileDesc = open("temp.txt",O_WRONLY|O_CREAT,00001);
	
	printf("-1\n");
	if(FileDesc == -1){
		printf("the FileDesc = -1\n");
		return (-1);
	}
	
	printf("-2\n");
	Flag = write(FileDesc,BufftoWrite,sizeof(BufftoWrite)); 
	if(Flag == -1){
		printf("writing  fails\n");
		return (-1);
	}
	printf("-3\n");
	Flag = close(FileDesc);
	if(Flag == -1){
		printf("closing  fails\n");
		return (-1);
	}
	
	//读阶段 
	
	FileDesc = open("/mnt/hgfs/2440/tem.txt",O_RDONLY,00777);
	FileDesc = open("temp.txt",O_RDONLY,00777);
	if(FileDesc == -1){
		printf("the FileDesc = -1\n");
		return (-1);
	}
	
	Flag = read(FileDesc,BuffertoRead,sizeof(BuffertoRead));
	if(Flag == -1){
		printf("reading  fails\n");
		return (-1);
	}
	
	printf("%s\n",BuffertoRead);
	//lseek阶段 
	Flag = lseek(FileDesc,5,SEEK_SET);
	if(Flag == -1){
		printf("lseeking  fails\n");
		return (-1);
	} 
	
	Flag = read(FileDesc,BuffertoRead,sizeof(BuffertoRead));
	if(Flag == -1){
		printf("reading  fails\n");
		return (-1);
	}
	
	printf("%s\n",BuffertoRead);
	
	Flag = close(FileDesc);
	if(Flag == -1){
		printf("closing  fails\n");
		return (-1);
	}
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值