(20220225)文件编程(API)

一、系统调用(API)

1、系统调用概念

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

2、为什么用户程序不能直接访问系统内核提供的服务呢?

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

3、用户编程接口(API)

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

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

 将程序的运行空间分为内核空间和用户空间(也就是常称的内核态和用户态)

4、Linux 文件

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

Linux文件可分为:普通文件(-),目录文件(d),链接文件(l),(硬件)设备文件(b/c),套接口文件(s),有名管道(p);

①普通文件类型
Linux中最多的一种文件类型, 包括 纯文本文件(ASCII);二进制文件(binary);数据格式的文件(data);各种压缩文件.第一个属性为 [-]
②目录文件
就是目录, 能用 # cd 命令进入的。第一个属性为 [d],例如 [drwxrwxrwx]
③块设备文件
块设备文件 : 就是存储数据以供系统存取的接口设备,简单而言就是硬盘。例如一号硬盘的代码是 /dev/hda1等文件。第一个属性为 [b]
④字符设备
字符设备文件:即串行端口的接口设备,例如键盘、鼠标等等。第一个属性为 [c]
⑤套接字文件
这类文件通常用在网络数据连接。可以启动一个程序来监听客户端的要求,客户端就可以通过套接字来进行数据通信。第一个属性为 [s],最常在 /var/run目录中看到这种文件类型
⑥管道文件
FIFO也是一种特殊的文件类型,它主要的目的是,解决多个程序同时存取一个文件所造成的错误。FIFO是first-in-first-out(先进先出)的缩写。第一个属性为 [p]
⑦链接文件
类似Windows下面的快捷方式。第一个属性为 [l],例如 [lrwxrwxrwx]

⑧堆栈文件

如LIFO。第一个属性为[f].

查看文件命令: ls -l 或(ls ll)--—查看文件; ls -ld -—查看路径; 

举例一:编写 filecpy.c 实现文件的复制。

 命令 :./filecpy  file1  file2

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

#define BUFF_SIZE 1024

int main(int argc, char *argv[])
{
    int fd_op;
    int fd_opa;
    int bytes_read;
    int bytes_write;
    char *ptr = NULL;
    char buff[BUFF_SIZE];
    
    if(3 != argc)
    {
	printf("please input file and aim file!\n");
	exit(0);
    }

    if((fd_op = open(argv[1], O_RDONLY)) == -1)
    {
	perror("open error!");
	exit(-1);
    }
    
    if((fd_opa = open(argv[2], O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
    {
	perror("open error!");
	close(fd_op);
    }

    while(bytes_read = read(fd_op, buff, 1024))
    {
	if(bytes_read < 0)
	{
	    perror("read error!");
	    break;
	}
	else
	{
	    ptr = buff;
	    while(bytes_write = write(fd_opa, ptr, bytes_read))
	    {
		if(bytes_write < 0)
		{
		    perror("write error!");
		    break;
		}
		else if(bytes_write < bytes_read)
		{
		    bytes_read -= bytes_write;
		    ptr += bytes_write;    
		}
		else if(bytes_write == bytes_read)
		{
		    break;
		}
	    }

	    if(bytes_write < 0)
	    {
		break;
	    }
	}
    }



    close(fd_op);
    close(fd_opa);

    return 0;
}

举例二 :编写一个如下所示的文件( three_hello.txt)

三个 hello 各占一行:

hello
hello
hello
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int i;
    int fd;
    int bytes_read;
    int bytes_write;
    char buff[5] = "hello";
    char filename[6];
    
    printf("please input filename:\n");
    scanf("%s", filename);

    if((fd = open(filename, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
    {
	perror("open erroe!");
	exit(-1);
    }

    for(i = 0; i < 3; i++)
    {
        if((bytes_write = write(fd, buff, 5)) == -1)
	{
	    perror("write error!");
	    break;
	}
	write(fd, "\n", 1);
    }

    lseek(fd, 0, SEEK_SET);

    for(i = 0; i < 3; i++)
    {
	memset(buff, 0, sizeof(buff));
        bytes_read = read(fd, buff, 5);
	write(1, buff, 5);
	memset(buff, 0, sizeof(buff));
        bytes_read = read(fd, buff, 1);
	write(1, buff, 1);
	
    }

    close(fd);
    return 0;
}

以上代码 将buff[5] 改为 buff[6] 会更简单!

二、C库函数

举例一:编写 filecpy.c 实现文件的复制。

 命令 :./filecpy  file1  file2

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *fp1;
    FILE *fp2;
    char ch;

    if((fp1 = fopen(argv[1], "r")) == NULL)
    {
        printf("not open file!\n");
        exit(0);
    }

    if((fp2 = fopen(argv[2], "w+")) == NULL)
    {
        printf("not open file!\n");
        fclose(fp1);
    }

    ch = fgetc(fp1);

    while(ch != EOF)
    {
        fputc(ch, fp2);
        ch = fgetc(fp1);
    }

    fclose(fp1);
    fclose(fp2);

    return 0;

举例二:合并文件

 方法一:按字符一个一个操作!

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *fp1;
    FILE *fp2;
    FILE *fp3;
    char ch1;
    char ch2;
    char ch;

    if((fp1 = fopen("text1.txt", "r")) == NULL)
    {
	printf("not open file!\n");
	exit(-1);
    }
    
    if((fp2 = fopen("text2.txt", "r")) == NULL)
    {
	printf("not open file!\n");
	fclose(fp1);
    }
    
    if((fp3 = fopen("text3.txt", "w+")) == NULL)
    {
	printf("not open file!\n");
	fclose(fp1);
	fclose(fp2);
    }
    
    ch1 = fgetc(fp1);
    ch2 = fgetc(fp2);

    while((ch1 != EOF) && (ch2 != EOF))
    {
	if((ch1 > '9') || (ch1 < '0'))
	{
	    fputc(ch1, fp3);
	}
	else
	{
	    ch = (((ch1 - '0') + (ch2 - '0')) + '0');
            fputc(ch, fp3);
	}

        ch1 = fgetc(fp1);
        ch2 = fgetc(fp2);
    }
    
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);

    return 0;
}

方法二:按照两位数相加,可以有进位。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE *fp1;
    FILE *fp2;
    FILE *fp3;
    char ch1;
    char ch2;
    char ch;
    int k;
    int j;
    int sum;
    int count = 0;
    int num1 = 0;
    int num2 = 0;

    if((fp1 = fopen("text1.txt", "r")) == NULL)
    {
	printf("not open file!\n");
	exit(-1);
    }

    if((fp2 = fopen("text2.txt", "r")) == NULL)
    {
	printf("not open file!\n");
	fclose(fp1);
    }
    
    if((fp3 = fopen("text3.txt", "w+")) == NULL)
    {
	printf("not open file!\n");
	fclose(fp1);
	fclose(fp2);
    }
  
    ch1 = fgetc(fp1);
    ch2 = fgetc(fp2);

    while((ch1 != EOF) && (ch2 != EOF))
    {
	if((ch1 > '9') || (ch1 < '0'))
	{
            fputc(ch1, fp3);
	}
        else
	{
	    k = (ch1 - '0');
	    j = (ch2 - '0');

	    num1 = num1*10 + k;
	    num2 = num2*10 + j;
	    count++;
	}

	if(2 == count)
	{
	    sum = num1 + num2;

	    ch = (sum/10 + '0');
	    fputc(ch, fp3);  
	    ch = (sum%10 + '0');
	    fputc(ch, fp3);  
            
	    num1 = 0;
	    num2 = 0;
	    count = 0;
	}
        
	ch1 = fgetc(fp1);
        ch2 = fgetc(fp2);
    }

    fclose(fp1);
    fclose(fp2);
    fclose(fp3);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值