文件编程的c库函数及文件应用实践

184 阅读3分钟

4月「掘金·日新计划」第3天

一、fopen与open

1.1、来源

  1. open是UNIX系统调用的函数
  2. fopen是标准C语言库函数

1.2、移植性

  1. fopen有良好移植性
  2. open只有在Linux下用

1.3、适用范围

  1. open,Linux下一切皆文件,硬件设备,网络套接字等
  2. fopen,普通正规文件

1.4、文件IO层次

  1. 低级IO,高级IO
  2. 谁离内核近

1.5、缓存

  1. 缓存文件系统,缓冲区,速度快,效率高,fopen
  2. 非缓存文件系统,通过内核访问,open

二、C库函数

2.1、fopen

参数:

  1. 文件名
  2. 什么权限,w+

返回值:

  1. FILE *fp

2.2、fwrite

参数:

  1. 缓冲区
  2. 一次写多少个字节
  3. 写多少次
  4. FILE *fp

返回值:

  1. 第三个参数

2.3、fread

参数:

  1. 缓冲区
  2. 一次写多少个字节
  3. 写多少次
  4. FILE *fp

返回值:

  1. 第三个参数

2.4、fseek

参数:

  1. fp

  2. 偏移值,0不偏移,正往后,负往前 针对whence偏移

  3. 光标移动到位置

    1. SEEK_SET,头
    2. SEEK_GND,尾
    3. SEEK_CUR,当前位置

2.5、fclose

参数:fp

2.6、fputc

写一个字符到文件,写多个字符可以配合for实现

参数:

  1. 一个字符
  2. fp

2.7、fget

从文件获取一个字符

参数:fp

返回值:获取到的字符char

2.8、feof

判断是否到达文件的尾

参数:fp

返回值:

  1. 到达尾,返回非0
  2. 未到达,返回0

2.10 ftell

ftell(FILE*fp)函数返回光标位置(相当于头和lseek返回值一样),c库函数

三、应用实践

3.1、cp命令实现

3.1.1、main函数参数

int main (int argc, char **argv)
{
    return 0;
}
  1. argc,参数总个数
  2. argv,char形二维数组,argv[0]...

3.7.2、cp实现

/***********************************************************************************
cp命令实现
​
***********************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
​
int main(int argc, char **argv)
{
    int fd;     //cp到的文件描述符
    int cpfd;   //cp的文件描述符
    int rsize = 0, wsize = 0;       //读写的个数
    int size = 0;           //文件大小
    char *buf = NULL;       //读缓冲区
    char input[10] = {'\0'};        //用户输入缓存if(argc < 3){           //判断main参数个数是否正确
        printf("Parameter error\n");    //参数错误
        goto Parameter;     //错误处理
    }
    printf("The number of parameters is correct...\n"); //参数数量正确
​
    cpfd = open(argv[1], O_RDONLY);     //打开cp的文件
    if(cpfd < 0){
        perror("target File open failed");  //打开失败,输出失败原因
        goto Parameter;
    }
    printf("%s open success...\n", argv[1]);    //文件打开成功
    
    size = lseek(cpfd, 0, SEEK_END);        //计算文件大小
    if(size < 0){
        perror("lseek error");          //失败并输出失败原因
        goto LseekError;
    }
    printf("document size %d...\n", size);  //文件大小
​
    buf = (char *)malloc(sizeof(char)*size);    //分配内存空间
    if(buf == NULL){
        printf("malloc error\n");           //失败并输出失败原因
        goto LseekError;
    }
    printf("malloc success...\n");  //内存分配成功if(lseek(cpfd, 0, SEEK_SET) < 0){       //光标指向头
        perror("lseek error");          //失败并输出失败原因
        goto LseekError;
    }
    printf("Cursor movement success...\n"); //光标移动成功
    
    rsize = read(cpfd, buf, size);          //读文件
    if(rsize < 0){
        perror("read error");           //失败并输出失败原因
        goto MallocError; 
    }
    printf("read %d byte success...\n",rsize);  //读取个数成功
    
    fd = open(argv[2], O_WRONLY|O_CREAT|O_EXCL, 0600);  //打开或创建文件
    if(fd < 0){                 //有错误
        if(errno == 17){                
            printf("File exists\n");        //错误是因为文件存在
            printf("Do you want to continue opening,yes/no?\n");    //是否继续打开
            scanf("%s",input);                      //输入yes打开文件并清除内容
            if(!strcmp("yes", input)){
                printf("Reopening file...\n");  //正在重新打开
                fd = open(argv[2], O_WRONLY|O_TRUNC);   
            }else{
                perror("target File open failed");
                goto MallocError;
            }
        }
    }
    if(fd < 0){                 //有错误
        perror("target File open failed");
        goto MallocError;
    }
    printf("%s open success...\n", argv[2]);    //文件打开成功
​
    wsize = write(fd, buf, size);           //写文件   
    if(wsize < 0){
        perror("write error");          //失败并输出失败原因
        goto WriteError; 
    }
    printf("wead %d byte success...\n",wsize);  //写入个数成功
    
    close(fd);
    free(buf);
    close(cpfd);
    printf("close %s success...\n",argv[2]);
    printf("malloc Memory release success...\n");
    printf("close %s success...\n",argv[1]);
    return 0;
​
WriteError:
    close(fd);
    printf("close %s success...\n",argv[2]);
MallocError:
    free(buf);
    printf("malloc Memory release success...\n");
LseekError:
    close(cpfd);
    printf("close %s success...\n",argv[1]);
Parameter:
    return -1;
}
  1. 判断参数是否正确
  2. 打开文件,lseek计算文件大小,malloc分配buf,read
  3. 创建或打开目标文件,wirte
  4. 关闭2文件,free内存空间