1. Linux系统调用及用户编程接口(API)
所谓系统调用是指操作系统提供给用户的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的的服务。
由于在Linux中,为了更好地保护内核空间,将程序的运行空间分为内核空间和用户空间(也就是常称的内核态和用户态),它们分别运行在不同的级别上,在逻辑上是相互隔离的。
因此,用户进程在通常情况下不允许访问内核数据,也无法使用内核函数,它们只能在用户空间操作用户数据,调用用户空间的函数。
系统调用并不是直接与程序员进行交互的,它仅仅是一个通过软中断机制向内核提交请求,以获取内核服务的接口。在实际使用中程序员调用的通常是用户编程接口—API
2. Linux文件
Linux一点哲学,“一切皆为文件”;在Linux中对目录和设备的操作都等同于对文件的操作,都是使用文件描述符来进行的。
当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读写文件时,也需要把文件描述符作为参数传递给相应的函数。
(1)open 函数
用于打开或创建文件,在打开或创建文件时可以指定文件的属性及用户的权限等各种参数。
程序如下:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
(以下程序头文件均如上省略)
int main()
{
int fd, ret;
fd = open("creat.c", O_RDWR| O_CREAT, 0666);
if(-1 == fd)
{
perror("open");
exit(1);
}
return 0;
}
注:1.O_CREAT 文件可存在可不存在,若不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取权限。
O_EXCL 使用时文件所创建的文件必须开始时不存在。
2. 以下三个常数中必须指定一个,且仅允许指定一个(这些常数定义在<fcntl.h>头文件中)
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读、写打开
(2)read 函数
程序如下:
int main()
{
int fd, ret;
char buf[100] = {0};
fd = open("creat.c", O_RDWR| O_CREAT, 0666);
if(-1 == fd)
{
perror("open");
exit(1);
}
ret = read(fd, buf, sizeof(buf));
if(-1 == ret)
{
perror("read");
exit(1);
}
printf("TXT is:%s\n", buf);
close(fd);
return 0;
}
(3)write 函数
程序如下:
int main()
{
int fd, ret;
char buf[100] = "helle world";
fd = open("creat.c", O_RDWR| O_CREAT, 0666);
if(-1 == fd)
{
perror("open");
exit(1);
}
ret = write(fd, buf, strlen(buf));
if(-1 == ret)
{
perror("write");
exit(1);
}
close(fd);
return 0;
}
例题:实现文件复制的功能
int main(int argc, char* argv[]) // 参数传递
{
int ret;
int fd[2] = {0}; // 建立一个数组的形式存放文件
char buf[100] = {0};
fd[0] = open(argv[1], O_RDONLY); //只读方式打开第一个文件
if(-1 == fd[0])
{
perror("open");
exit(1);
}
fd[1] = open(argv[2], O_RDWR | O_CREAT | O_EXCL, 066); // 可读可写的方式打开第二个文件
if(-1 == fd[1])
{
perror("open");
exit(1);
}
while((ret = read(fd[0], buf, sizeof(buf))) != 0) // 循环读取 fd[0] 的内容,并存进 buf
{
ret = write(fd[1], buf, ret); // 把读取的内容写进 fd[1]
if(-1 == ret)
{
perror("write");
exit(1);
}
memset(buf, 0, sizeof(buf)); // 最后清空 buf
}
return 0;
}
3. 标准库函数
C库函数的文件操作是独立于具体的操作系统平台的,不管是在DOS、Windows、Linux还是在VxWorks中都是这些函数。
(1)创建和打开
r, rb : 只读方式打开,文件必须已存在
w,wb : 只写方式打开,如果文件不存在则创建, 如果文 件已存在清空重写
a, ab: 只能在文件末尾追加数据,如果文件不存在则创建
r+,rb+,r+b: 读写方式打开,文件必须已存在
w+,w+b,wb+: 读写方式打开,如果文件不存在则创建,如果文件已存在清空重写
a+,a+b,ab+: 读和追加方式打开,如果文件不存在则创建
程序如下:
int main()
{
FILE *fp;
fp = fopen("xx.c", "r");
if(NULL == fp)
{
perror("fopen");
exit(1);
}
return 0;
}
(2)读写
对文件的读和写是最常用的文件操作。在linux C中提供了多种文件读写的函数:
字符读写函数 :fgetc和fputc
字符串读写函数:fgets和fputs
数据块读写函数:fread和fwrite
格式化读写函数:fscanf和fprintf
over.