Linux系统编程-文件IO

系统调用

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

由于在Linux中,为了更好地保护内核空间,将程序的运行空间分为内核空间和用户空间(也就是常称的内核态和用户态),它们分别运行在不同的级别上,在逻辑上是相互隔离的。因此,用户进程在通常情况下不允许访问内核数据,也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间的函数。

用户编程接口API

系统调用并不是直接与程序员进行交互的,它仅仅是一个通过软中断机制向内核提交请求,以获取内核服务的接口。在实际使用中程序员调用的通常是用户编程接口—API

系统命令相对API更高了一层,它实际上一个可执行程序,它的内部引用了用户编程接口(API)来实现相应的功能

系统命令与系统调用 API的关系

Linux文件

Linux一点哲学,“一切皆为文件”;在Linux中对目录和设备的操作都等同于对文件的操作;

Linux文件可分为:-普通文件,d目录文件,c/b设备文件、l链接文件(p管道文件、s套接字、f堆栈文件);

文件既可以通过C库函数也可以通过API(系统调用)。

文件IO:初级IO(系统调用API),标准IO(库函数),高级IO(高级API)

☆如何获取系统调用的错误信息:

方法1:借助errno全局变量 缺点:全面异常处理时,工作量大;全局属性危险,手动检测异常;

方法2:库函数 perror (封装处理errno全局变量)(常用)

方法3:strerror

文件描述符

文件描述符是一个非负的整数,它是一个索引值,并指向内核中每个进程的记录表中;

一个进程启动时,都会自动打开三个文件:    

标准输入:       STDIN_FILENO                  键盘 :0    

标准输出:       STDOUT_FILENO              显示器:1    

标准出错处理:STDERR_FILENO               2

系统调用- 创建

int creat(const char *filename, mode_t mode )    

filename :创建的文件名(包含路径,缺省为当前路径)    

mode:创建模式

常创建模式:    

S_IRUSR      所有者可读

S_IWUSR     所有者可写    

S_IXUSR      所有者可执行    

S_IXRWU     所有者可读、可写、可执行    

除用以上宏来选择创建模式,也可以用数字来表示

其中USR可换成:(1)GRP 分组;(2)OTH 第三方

系统调用-打开

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

int open(const char *pathname, int flags); (不创建新文件)

int open(const char *pathname,int flags,mode_t mode); (创建新文件)

返回值:成功返回新分配的文件描述符(正整数),出错返回-1并设置errno

参数含义

pathname是要打开或创建的文件的名字

flags参数可用来说明此函数的多个选择项

 以下三个常数中必须指定一个,且仅允许指定一个(这些常数定义在<fcntl.h>头文件中)      

O_RDONLY   只读打开      

O_WRONLY  只写打开      

O_RDWR       读、写打开

O_APPEND    追加(只写方式)

以下可选项可以同时指定0个或多个, 和必选项按位或起来作为flags参数。    

O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取权限。          

O_NONBLOCK 如果p a t h n a m e指的是一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I / O操作设置非阻塞方式。

O_EXCL 不能单独用,需要与O_CREAT一起使用,如果指定文件存在,则error。例:O_CREAT | O_EXCL

O_TRUNC 将打开文件长度截短为零,相当于清空,不能与O_RDONLY搭配使用

O_WRONLY|O_CREAT|O_TRUNC  相当于 CREAT( )

mode对于open函数而言,仅当创建新文件时才使用第三个参数

系统调用-关闭

当我们操作完文件以后,需要关闭文件:int close(int fd)     fd: 文件描述符,来源?

系统调用-读

int read(int fd, const void *buf, size_t length)    

功能:    

从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数。存在部分读的问题。

read函数返回0的情形:遇到EOF(文件结束标志)。

系统调用-写

int write(int fd, const void * buf, size_t length)    

功能:     

把length个字节从buf指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数。存在部分写的问题。

write函数一般情况不会返回0,即使遇到EOF,仅在指针链长度为0时才返回0。

系统调用-定位

int lseek(int fd, offset_t offset, int whence)    

功能:    

将文件读写指针相对whence移动offset个字节。操作成功时,返回文件指针相对于文件头的位置

whence可使用下述值:
SEEK_SET:相对文件开头
SEEK_CUR:相对文件读写指针的当前位置
SEEK_END:相对文件末尾

offset可取负值,表示向前移动

例如下述调用可将文件指针相对当前位置向前移动5个字节:
lseek(fd, -5, SEEK_CUR)

如何利用lseek来计算文件长度:

由于lseek函数的返回值为文件指针相对于文件头的位置,因此下面调用的返回值就是文件的长度: lseek(fd, 0, SEEK_END)

库函数

C库函数的文件操作是独立于具体的操作系统平台的,不管是在DOS、Windows、Linux还是在VxWorks中都是这些函数。(不直接对磁盘读写)

库函数-创建和打开

FILE *fopen(const char *filename, const char *mode)    

filename:打开的文件名(包含路径,缺省为当前路径)    

mode:打开模式

“r” :只读,文件必须已存在

“w”:只写,如果文件不存在则创建,如果文件已存在则把文件长度截断(Truncate)为0字节再重新写,也就是替换掉原来的文件内容

“a”:只能在文件末尾追加数据,如果文件不存在则创建

“r+”:允许读和写,文件必须已存在

“w+”:允讲读和写,如果文件不存在则创建,如果文件已存在则把文件长度截断为0字节再重新写

“a+”:允许读和追加数据,如果文件不存在则创建

b用于区分二进制文件和文本文件,这一点在DOS、Windows系统中是有区分的,但Linux不区分二进制文件和文本文件

库函数-读

size_t  fread(void *ptr, size_t size, size_t n, FILE* stream)    

功能:   

stream指向的文件中读取n个字段每字段为size字节,并将读取的数据放入ptr所指的字符数组中,返回实际已读取的字段数

库函数-写

size_t fwrite (const void *ptr, size_t size, size_t n,FILE *stream)    

功能:    

缓冲区ptr所指的数组中把n个字段写到stream指向的文件中每个字段长为size个字节,返回实际写入的字段数

库函数-读字符

int fgetc(FILE *stream)                                从指定的文件中读一个字符

#include<stdio.h>
main()
{
    FILE *fp;
    char ch;
    if((fp=fopen("c1.txt","rt"))==NULL)
    {
   	    printf("\nCannot open file strike any key exit!");
   	    getchar();
 	    exit(1);
	}
	ch=fgetc(fp);
	while(ch!=EOF)
	{
	    putchar(ch);
		ch=fgetc(fp);
	}
	fclose(fp);
}

库函数-写字符

int fputc(int c, FILE *stream)                   向指定的文件中写入一个字符

#include<stdio.h>
main()
{
    FILE *fp;
	char ch;
	if((fp=fopen("string","wt+"))==NULL) 
    {
	    printf("Cannot open file,strike any key exit!");
		getch();
		exit(1);
	}
	printf("input a string:\n");
	ch=getchar();
	while (ch!='\n') 
    {
		fputc(ch,fp);
		ch=getchar();
	}
	printf("\n");
	fclose(fp);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值