Linux系统应用编程(一)文件编程

Linux系统应用编程(一)文件编程

一、Linux文件I/O

1.打开文件

▲ 函数原型:int open(const char *pathname,int flagsmode_mode)

在这里插入图片描述

  • Linux文件权限:三位十进制分别表示用户、组用户、其他用户对该文件的权限。
    在这里插入图片描述
2.写文件

▲ 函数原型:ssize_t write(int fd, const void *buf, size_t count);

3.读文件

▲ 函数原型:ssize_t read(int fd, void *buf, size_t count);

4.操作文件指针

▲ 函数原型:off_t lseek(int fd, off_t offset, int whence);

在这里插入图片描述

【4-1】应用:lseek( )计算文件大小
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char **argv){
    if(argc != 2){
        printf("error.Usage:count fileName\n");
        exit(-1);
    }
    int fd;
    fd = open(argv[1],O_RDONLY);
   // lseek(fd,0,SEEK_SET);   //默认打开文件时的文件指针在头
    int fileSize = lseek(fd,0,SEEK_END);    //lssek让指针偏移到文件尾,偏移了多少就是文件的大小
    printf("%s size:%d\n",argv[1],fileSize);
    close(fd);
    return 0;
}

在这里插入图片描述

5.实现cp命令
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc,char **argv){

    
    if(argc != 3){
        printf("copy:error.Usage:copy srcFile destFile\n");
        exit(-1);
    }
    int srcFd = open(argv[1],O_RDONLY);
    if(srcFd == -1){
        perror("open");
        exit(-1);
    }
    int destFd = open(argv[2],O_RDWR | O_CREAT,0600);
    if(destFd == -1){
        perror("open");
        exit(-1);
    }
    /* 计算源文件的大小 */
    off_t size = lseek(srcFd,0,SEEK_END);
    lseek(srcFd,0,SEEK_SET);    //让文件指针回到原位置
    char *readBuffer = (char *)malloc(size);    //文件多大就申请多大的空间
    ssize_t cnt = read(srcFd,readBuffer,size);
    write(destFd,readBuffer,cnt);
    close(srcFd);
    close(destFd);
    return 0;
}

在这里插入图片描述

二、标准I/O

1.文件IO和标准IO的区别?
  • 文件IO:直接调用内核提供的系统调用函数,一般特定于Linux/Unix平台。其操作文件机制不经过内核的缓存(无缓存),数据直接在磁盘和应用程序地址空间进行传输。
  • 标准IO:间接调用内核提供的系统调用函数(先调用C库,再到内核的系统调用),不限于平台,且实现的跨平台的缓存(包括行缓存、全缓存、无缓存几种类型),所有其执行效率会优于文件IO。
2.打开文件

▲ 函数原型:FILE *fopen(const char *pathname, const char *mode, FILE *stream);
在这里插入图片描述

3.读文件

▲ 函数原型:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

4.写文件

▲ 函数原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

▲ 参数解释:

  • pstr:存放本次读取/写入的存储空间
  • size:读取/写入一个数据元素的大小
  • nmemb:本次读取/写入的数据大小
  • stream:读取/写入的文件流

▲ 返回值:

  • 读取/写入成功:返回nmemb,即读取/写入成功的元素个数
  • 读取/写入失败:返回0
    文档中所述,对于返回值为0的情况,不区分是读取/写入失败了还是文件结束了
5.移动文件指针

▲ 函数原型:int fseek(FILE *stream, long offset, int whence);

  • fseek( )和lseek( )不同,fseek( )返回值:如果成功,则该函数返回零,否则返回非零值。

    在计算文件大小时,需要配合ftell( )使用实现。

6.实现cp命令
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char **argv){

    if(argc != 3){
        printf("Error.Usage:%s srcFile desFile\n",argv[0]);
        return -1;
    }

    /* 打开源文件和目标文件 */
    FILE *fpSrc = fopen(argv[1],"r");  //返回文件流指针
    FILE *fpDes = fopen(argv[2],"w+");

    if(fpSrc == NULL || fpDes == NULL){
        perror("fopen");
        exit(-1);
    }

    /* 计算源文件大小 */
    fseek(fpSrc,0,SEEK_END);
    long int srcSize = ftell(fpSrc);
    printf("fileSize:%ld\n",srcSize);

    fseek(fpSrc,0,SEEK_SET);


    char *buffer = (char *)malloc(srcSize);
    int readSize = 0;

    while( (readSize = fread(buffer,4,1024*4,fpSrc)) != 0){
        printf("readSize:%d\n",readSize);
        fwrite(buffer,4,readSize,fpDes);
    }
    printf("copy done\n");
    return 0;
}

在这里插入图片描述

7.其他函数fgetc()、fpurc( )、feof( )

三、目录IO

1.函数原型
  • DIR *opendir(const char *name);
  • DIR *fdopendir(int fd);
  • int mkdir(const char *pathname, mode_t mode);
  • struct dirent *readdir(DIR *dirp);
2.应用:打印输出指定目录下的所有文件名个inode号
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>

int main(int argc,char **argv){

    DIR *dp = NULL;
    char isCreate = 'n';
    struct dirent *p = NULL;

    if(argc != 2){
        printf("error.Usage:%s [dirName]\n",argv[0]);
        exit(-1);
    }

reopen:
    dp = opendir(argv[1]);   //打开目标目录
    if(dp == NULL){          //打开失败,如果是目录不存在,询问是否创建该目录
        printf("No such direcory\nDo you want to create %s?[y/n] ",argv[1]);
        scanf("%c",&isCreate);
        if(isCreate == 'y'){
            mkdir(argv[1],0666);    //创建目录
            goto reopen;
        }else{
            printf("done\n");
            exit(-2);
        }
    }
    /* 读出目录下所有文件的inode号和name(排除.和..) */
    while((p = readdir(dp)) != NULL){
        if( strcmp(p->d_name,".") && strcmp(p->d_name,"..")){
            printf("Inode:%ld\t name:%s\n",p->d_ino,p->d_name);
        }
    }
    closedir(dp);
    return 0;
}

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AF_INET6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值