如何在c中创建文件的精确副本

时间:2012-05-10 13:48:05

标签: c

我想在c

中创建文件(.bmp)的精确副本
#include<stdio.h>

int main()
{
    FILE *str,*cptr;

    if((str=fopen("org.bmp","rb"))==NULL)
    {
        fprintf(stderr,"Cannot read file\n");
        //return 1;
    }

    if((cptr=fopen("copy.bmp","wb"))==NULL)
    {
        fprintf(stderr,"Cannot open output file\n");
        //return 1;
    }

    fseek(str, 0, SEEK_END);
    long size=ftell(str);
    printf("Size of FILE : %.2f MB \n",(float)size/1024/1024);
    char b[2];

    for(int i=0;i<size;i++)
    {
        fread(b,1,1,str);
        fwrite(b,1,1,cptr);
    }

    fseek(cptr, 0, SEEK_END);
    long csize=ftell(str);
    printf("Size of created FILE : %.2f MB \n",(float)csize/1024/1024);
    fclose(str);
    fclose(cptr);

    return 0;
}

虽然它创建了一个大小相同的文件,但是在尝试查看新创建的位图副本时,Windows会引发错误。 为什么会这样?

5 个答案:

答案 0 :(得分:7)

在开始阅读之前,您已将输入文件的文件指针移动到文件末尾。您需要将其恢复到开头。

变化:

fseek(str, 0, SEEK_END);
long size=ftell(str);

为:

fseek(str, 0, SEEK_BEGIN);
long size=ftell(str);
fseek(str, 0, SEEK_SET);

请注意,您的代码没有错误检查 - 如果您至少检查过fread的结果,那么您的错误就会立即显现出来。带回家的信息:在进行错误检查时不要偷工减料 - 它会在以后支付股息。

答案 1 :(得分:3)

你需要回到原始文件的开头,因为你不断阅读EOF,因此不会复制文件内容,只是你的b []数组中发生了什么。

您没有检查fread()和fwrite()的返回码。如果你这样做,你可能已经从返回码中解决了这个问题。

答案 2 :(得分:1)

如果检查原始文件的大小和以字节为单位的副本,它应该告诉您问题。

此代码读取一个字节并写入一个字节。

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

#define KB 1024

int main()
{
    unsigned int ifd,ofd,rcnt;
    char buf[KB];

    ifd=open("orig.jpg",O_RDONLY);
    if(ifd==0)
    {
        fprintf(stderr,"Cannot read file\n");
        //return 1;
    }

    ofd=open("copy.jpg",O_WRONLY|O_CREAT);
    if(ofd==0)
    {
        fprintf(stderr,"Cannot open output file\n");
        //return 1;
    }

    while(rcnt=read(ifd,buf,KB))
        write(ofd,buf,rcnt);
}

答案 3 :(得分:1)

这是一个很好的复制文件功能!复制char char比读取整个文件更好,因为该结果(如果文件很长)是缓冲区溢出!

double copy(char *input, char *output) {
    FILE *f_in = fopen(input, "r");
    FILE *f_out = fopen(output, "a");
    if (!f_in || !f_out) {
        fclose(f_in);
        fclose(f_out);
        return -1;
    }
    int c;
    while ((c = fgetc(f_in)) != EOF)
        fputc(c, f_out);
    fclose(f_in);
    fseek(f_out, 0, SEEK_END);
    long size = ftell(f_out);
    fclose(f_out);
    return (double)(size / 1024 / 1024); // MB
}

此函数返回输出文件的MB。如果不成功,则返回0

使用此功能:

double output;
if ((output = copy("What ever you want to copy", "Where ever it should be printed")) != -1)
    printf("Size of file: %lf MB.\n", output);

希望这会有所帮助:)

答案 4 :(得分:0)

我处理了你的第一个代码,并且还使用了第一个解决方案,只需要将这个代码添加到你的程序中:fseek(str,0,SEEK_SET);并完成你的复制位图。