C语言 文件大小,分配空间,读入文件,写入文件,实现复制的功能

首先通过两种方法得到文件的大小,字节为单位,根据这个大小使用malloc分配固定的空间buffer,二进制流读入文件,把二进制流写入buffer中,buffer输出写入到新的文件。
源文件1.txt,输出文件1.txt.txt
环境为Ubuntu 16.04,gcc

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

#include <sys/stat.h>
//get file size
int file_size(char *filename)
{
    struct stat statbuf;
    stat(filename, &statbuf);
    int size = statbuf.st_size;
    printf("the size of file %s is : %d byte\n", filename, size);
    return size;
}

long file_size2(FILE *file)
{
    /* 获取文件大小 */
    fseek (file, 0, SEEK_END);
    long lSize;
    lSize = ftell (file);
    rewind (file);//point back to the begin
    printf("the size of file is : %ld byte\n",  lSize);
    return lSize;
}

//inputName: 1.txt  -> outputName:1.txt.txt
void initOutname(char *filename)
{
    int nameLen = strlen(filename), suffixLen = 0;
    char *first = strrchr(filename, '.');
    if (first == NULL) return ;
    strcat(filename, first);
}

int main(int argc, char *argv[])
{
    char *buffer = NULL;
    char filename[100];
    if(argc == 1){
    	strcpy(filename, "1.txt");
    }else if(argc == 2){
    	strcpy(filename, argv[1]);
    }else {
    	printf("parameter ERROR!\n");
    	return -1;
    }
    int len = file_size(filename);

    FILE *file = fopen(filename, "rb");
    if (!file)
    {
        printf("%s: can not open %s\n", __func__, filename);
        return -1;
    }

    long llen = file_size2(file);

    //len bytes
    buffer = malloc(llen);
    // printf("%ld\n", sizeof(char));
    if(NULL != buffer)
    {
        printf("success\n");
    }
    else
    {
        printf("the file is too large to load!\n");
        return -1;
    }
    /* 将文件拷贝到buffer中 */
    size_t result = fread (buffer, 1, llen, file);

    if (result != llen)
    {
    	printf("fread ERROR\n");
        return -1;
    }
    printf("%ld\n", result);
    printf("%s\n", buffer);

    initOutname(filename);
    FILE *fileOut = fopen(filename, "w+");
    if (!fileOut)
    {
        printf("%s: can not open %s\n", __func__, filename);
        return -1;
    }
    result = fwrite(buffer, 1, llen, fileOut);
    if (result != llen)
    {
        printf("%s: can not write %s\n", __func__, filename);
        return -1;
    }

    fclose (fileOut);
    fclose (file);
    free(buffer);
    return 0;
}

在测试大文件(5G)大小时候,第一种方法测出只有1G,第二种方法比较准确,原因还未知,读者知道的麻烦告诉下~

ant@antBox:/workfile$ ./test /media/sf_share/16.04.vdi
the size of file /media/sf_share/16.04.vdi is : 1075838976 byte
the size of file is : 5370806272 byte
success

第一种方法是一次性申请读入文件大小的内存空间buffer,一次性写入buffer,再输出到文件中,但文件特别大时候,malloc时候就失败了,解决方法是申请固定size大小的buffer,得到文件的大小len,每次写入size字节的内容,更新len为len-size,刚开始判断len<size,如果是的话则写入len大小。最终退出循环时,len减为0
在这里插入图片描述
更新后的代码使用第二种文件大小得到方法,代码如下:

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

#define MAXSIZE 32768

#include <sys/stat.h>

//inputName: 1.txt  -> outputName:1.txt.txt
void initOutname(char *filename)
{
    int nameLen = strlen(filename), suffixLen = 0;
    char *first = strrchr(filename, '.');
    if (first == NULL) return ;
    strcat(filename, first);
}

long file_size2(FILE *file)
{
    /* 获取文件大小 */
    fseek (file, 0, SEEK_END);
    long lSize;
    lSize = ftell (file);
    rewind (file);//point back to the begin
    printf("the size of file is : %ld byte\n",  lSize);
    return lSize;
}

int main(int argc, char *argv[])
{
    char *buffer = NULL;
    char filename[100];
    if(argc == 1)
    {
        strcpy(filename, "1.txt");
    }
    else if(argc == 2)
    {
        strcpy(filename, argv[1]);
    }
    else
    {
        printf("parameter ERROR!\n");
        return -1;
    }

    FILE *file = fopen(filename, "rb");
    if (!file)
    {
        printf("%s: can not open %s\n", __func__, filename);
        return -1;
    }

    initOutname(filename);
    FILE *fileOut = fopen(filename, "w");
    fclose (fileOut);
    fileOut = fopen(filename, "a+");
    if (!fileOut)
    {
        printf("%s: can not open %s\n", __func__, filename);
        return -1;
    }

    buffer = malloc(MAXSIZE);
    if(NULL != buffer)
    {
        printf("success\n");
    }
    else
    {
        printf("%s the file is too large to load!\n", __func__);
        return -1;
    }
    /* 将文件拷贝到buffer中 */
    int bytes_read = 0;
    int onceSize = MAXSIZE;
    int len = file_size2(file);
    for(; len > 0; len -= onceSize)
    {
        if(len < MAXSIZE) onceSize = len;

        fread (buffer, 1, onceSize, file);
        fwrite(buffer, 1, onceSize, fileOut);
    }

    fclose (fileOut);
    fclose (file);
    free(buffer);
    return 0;
}

其中打开输出文件方式先使用w目的是新建并清空之前的文件内容,再用二进制追加a+的方式打开。
判断生成的文件和源文件的sha224的值:

ant@antBox:/workfile/SHA$ ./sha sha224 ../1.txt
File('../1.txt'): a069a467f410fae0559382f1e45ec9a850e1e26472eac466588291c7
ant@antBox:/workfile/SHA$ ./sha sha224 ../1.txt.txt
File('../1.txt.txt'): a069a467f410fae0559382f1e45ec9a850e1e26472eac466588291c7

其中读入再写入有一种简单的写法,思想和图片一样。读入了byte_read字节,那么就写入byte_read字节到文件中。

    // int onceSize = MAXSIZE;
    // int len = file_size2(file);
    // for(; len > 0; len -= onceSize)
    // {
    //     if(len < MAXSIZE) onceSize = len;

    //     fread (buffer, 1, onceSize, file);
    //     fwrite(buffer, 1, onceSize, fileOut);
    // }

    while(bytes_read=fread (buffer, 1, MAXSIZE, file))
    	fwrite(buffer, 1, bytes_read, fileOut);
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值