一些的简单的io小程序

1.统计文件的字节数目大小

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


/*
使用方法:./a.out file
*/
int main(int argc, char *argv[])
{
    if(argc != 2) {
        fprintf(stderr, "Error used!");
        exit(-1);
    }

    FILE *fd;
    int ch = 0; //统计字节数目

    fd = fopen(argv[1], "r");   //以只读的方式打开
    if(fd == NULL) {
        perror("fopen() failed!");
        exit(-1);
    }

   /*   方式1
    while(fgetc(fd) != EOF) {
        ch++;
    }
    
    printf("Count = %d\n", ch);
    */

   /*   方式2
    fseek(fd, 0, SEEK_END);
    printf("Count = %ld\n", ftell(fd));

    */
   
    fclose(fd);
    exit(0);
}

方式③:

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

static off_t flen(const char *filename)
{
    struct stat buf;
    if(stat(filename, &buf) < 0) {
        perror("stat()");
        exit(-1);
    }
    return buf.st_size;
}


int main(int argc, char *argv[])
{
    if(argc != 2) {
        fprintf(stderr, "Error used!\n");
        exit(-1);
    }

    printf("cnt = %lld\n", (long long)flen(argv[1]));
    exit(0);
}

效果:

2.按行读取文件内容,并打印每行大小和申请的存储空间大小

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


int main(int argc, char *argv[])
{
    if(argc != 2) {
        fprintf(stderr, "Error used!\n");
        exit(-1);
    }

    FILE *fd;
    char *linebuf = NULL;  //保存读取文件
    size_t linesize = 0; //保存存储空间大小

    
    fd = fopen(argv[1], "r");
    if(fd == NULL) {
        perror("fopen()!");
        exit(-1);
    }

    while(1) {
        if(getline(&linebuf, &linesize, fd) < 0) break; //终止条件
        printf("strlen = %ld\n", strlen(linebuf));    //实际大小
        printf("size = %ld\n", linesize);
    }

    free(linebuf);
    fclose(fd);  //关闭
    exit(0);
}

效果:

        testd.c文件内容

3.实现文件的copy 

标准IO:

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

#define BUFFSIZE 1024

int main(int argc, char *argv[])
{
    FILE *fds, *fdd;    //源和目标文件
    char buf[BUFFSIZE]; 

    if(argc != 3) {
        fprintf(stderr, "Erroe used:%s\n", argv[0]);
        exit(-1);
    }
    fds = fopen(argv[1], "r");
    if(fds == NULL) {
        perror("fopen() fds");
        exit(-1);
    }

    fdd = fopen(argv[2], "w");
    if(fdd == NULL) {
        perror("fopen() fdd");
        exit(-1);
    }

    while(fgets(buf, BUFFSIZE, fds) != NULL) {
        fputs(buf, fdd);
    }

    fclose(fdd);
    fclose(fds);

    exit(0);
}

文件IO:

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

#define BUFSIZE 1024

//argv[1]:源文件
//argv[2]:目标文件
int main(int  argc, char *argv[])
{

    if(argc != 3) {
        fprintf(stderr, "Usage failed!\n");
        exit(-1);
    }

    int fds, fdd;   //定义文件描述符
    int len, ret, pos;
    char buf[BUFSIZE];

    fds = open(argv[1], O_RDONLY);
    if(fds == -1) { //打开失败
        perror("open fds failed!");
        exit(-1);
    }
    fdd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if(fdd == -1) { //打开失败
        perror("open fdd failed!");
        exit(-1);
    }

    pos = 0;
    while(1) {
        len = read(fds, buf, BUFSIZE);  //从fds中读取BUFSIZE个字节到buf中
        if(len < 0) {
            perror("read");
            exit(-1);
        }
        if(len == 0) break; //len = 0表示没东西可以读了

        while(len) {
            ret = write(fdd, buf + pos, len); //从buf中写len长度个字节到fdd中
            if(ret < 0) {
                perror("write");
                exit(-1);
            }
            pos += ret;
            len -= ret;
        }
        pos = 0;
    }
    close(fds);
    close(fdd);

    exit(0);
}

4.打印文件的类型 

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


static int ftype(const char *filename)
{
    struct stat buf;
    stat(filename, &buf);

    if(S_ISREG(buf.st_mode)) return '-';    //常规文件
    else if(S_ISDIR(buf.st_mode)) return 'd';   //目录文件
    else if(S_ISCHR(buf.st_mode)) return 'c';   //字符设备文件
    else if(S_ISBLK(buf.st_mode)) return 'b';  //块设备文件
    else if(S_ISFIFO(buf.st_mode)) return 'f'; //管道文件
    else if(S_ISLNK(buf.st_mode)) return 'l'; //链接文件
    else if(S_ISSOCK(buf.st_mode)) return 's'; //socket文件
    else return '?';    //异常
}


int main(int argc, char *argv[])
{
    if(argc != 2) {
        fprintf(stderr, "Errur used!\n");
        exit(-1);
    }
    printf("type = %c\n",ftype(argv[1]));

    exit(0);
}

效果:

5.读取目录文件 

方法一:

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

#define PAT "/etc/*"

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

    glob_t globes;

    int err;

    err = glob(PAT, 0, NULL, &globes);  //模式为PAT,不追加功能,不保存错误路径和错误码,将目录解析后存入globes
    if(err) {
        printf("Error code  = %d\n",err);
        exit(-1);
    }

    for(int i = 0;i < globes.gl_pathc;i++) 
        puts(globes.gl_pathv[i]);   //打印解析后的目录

    globfree(&globes);
    exit(0);
}

方法二:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>

#define PAT "/etc"

int main()
{
    DIR *dp;
    struct dirent *cur;

    dp = opendir(PAT);
    if(dp == NULL) {
        perror("opendir()");
        exit(-1);
    }

    while((cur = readdir(dp)) != NULL)
        puts(cur->d_name);
    
    closedir(dp);

    exit(0);
}

6.模擬du命令 

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <glob.h>

#define PATHSIZE 1024

/* 判断是否为“.”或者“..” */
static int path_noloop(const char *path)
{
    char *pos;

    pos = strrchr(path, '/');   //找到最右边的'/'
    if(strcmp(pos+1, ".") == 0 || strcmp(pos+1, "..") == 0)
        return 0;
    return 1;
}

static int64_t mydu(const char *pathname)
{
    struct stat statres;
    static char nextpath[PATHSIZE];
    glob_t globres;
    int i;
    int64_t sum;

    if(lstat(pathname, &statres) < 0) {
        perror("lstat()");
        exit(-1);
    }

    /*mydu分为两种情况,非目录和目录*

    非目录文件可以直接返回文件大小
    目录文件需要对目录进行解析
    */

    if(!S_ISDIR(statres.st_mode)) { /*非目录直接返回*/
        return statres.st_blocks; 
    }

    /*是目录,进行解析 *和.* */
    strncpy(nextpath, pathname, PATHSIZE);
    strncat(nextpath, "/*", PATHSIZE - 1);
    glob(nextpath, 0, NULL, &globres);

    strncpy(nextpath, pathname, PATHSIZE);
    strncat(nextpath, "/.*", PATHSIZE - 1);
    // 把解析到的结果追加到globres中
    glob(nextpath, GLOB_APPEND, NULL, &globres);
    
    sum = 0;
    for(i = 0; i < globres.gl_pathc; i++)
    {
        if(path_noloop(globres.gl_pathv[i]))
        sum += mydu(globres.gl_pathv[i]);
    }
    sum += statres.st_blocks;
    
    globfree(&globres);
    return sum;    
}

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

    if(argc < 2) {
        fprintf(stderr, "Used errod()!\n");
        exit(-1);
    }

    printf("%lld\n", mydu(argv[1]) / 2);

    exit(0);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值