【问题标题】:Copying a file in C with fwrite使用 fwrite 在 C 中复制文件
【发布时间】:2013-01-04 02:52:51
【问题描述】:

我是 C 的新手,我正在尝试编写一个程序来复制文件,以便我可以学习文件的基础知识。我的代码将一个文件作为输入,通过使用 fseek 和 ftell 减去它的开头来计算它的长度。然后,它使用 fwrite 写入,基于我可以从它的手册页中获得的内容,一个数据元素,(END - START)元素长,到 OUT 指向的流,从 FI 给出的位置获取它们。问题是,尽管它确实产生了“复制输出”,但该文件与原始文件不同。我究竟做错了什么?我尝试将输入文件读入一个变量,然后从那里写入,但这也无济于事。我究竟做错了什么? 谢谢

int main(int argc, char* argv[])
{ 
    FILE* fi = fopen(argv[1], "r"); //create the input file for reading

    if (fi == NULL)
        return 1; // check file exists

    int start = ftell(fi); // get file start address

    fseek(fi, 0, SEEK_END); // go to end of file

    int end = ftell(fi); // get file end address

    rewind(fi); // go back to file beginning

    FILE* out = fopen("copy output", "w"); // create the output file for writing

    fwrite(fi,end-start,1,out); // write the input file to the output file
}

这应该有效吗?

{
    FILE* out = fopen("copy output", "w");
    int* buf = malloc(end-start);  fread(buf,end-start,1,fi);
    fwrite(buf,end-start,1,out);
}

【问题讨论】:

  • 在您的fwrite() 调用中,第一个参数应该是指向内存中文件内容的指针(我在这里看不到您在哪里阅读)而不是fi 本身。
  • @Zach49899 你可以使用open(), read(), write() 系统调用。这更容易。

标签: c file-io copy fwrite


【解决方案1】:

fwrite 不是这样工作的。

要复制文件,您通常会分配一个缓冲区,然后使用fread 读取一个数据缓冲区,然后使用fwrite 将该数据写回。重复直到你复制了整个文件。典型的代码是这样的一般顺序:

#define SIZE (1024*1024)

char buffer[SIZE];
size_t bytes;

while (0 < (bytes = fread(buffer, 1, sizeof(buffer), infile)))
    fwrite(buffer, 1, bytes, outfile);

【讨论】:

  • 在 while 结束时不是缺少一个 ')' 吗?
  • @SvenBamberger:哎呀,是的,看起来有。谢谢。
  • @JerryCoffin 它也适用于非常规文件吗?
  • @alhelal:你想到了什么样的“非常规文件”?
  • @alhelal:文件分为两类:文本和二进制文件。任何不是纯文本的都是二进制的,所以那些都是二进制的。
【解决方案2】:

fwrite 的第一个参数是指向要写入文件的数据的指针,而不是要读取的 FILE*。您必须将第一个文件中的数据读入缓冲区,然后将该缓冲区写入输出文件。 http://www.cplusplus.com/reference/cstdio/fwrite/

【讨论】:

  • 你是这个意思吗? FILE* out = fopen("复制输出", "w"); int* buf = malloc(end-start); fread(buf,end-start,1,fi); fwrite(buf,end-start,1,out);
  • 你有一个大致的想法,但对于大文件,你必须分段完成。
  • 有什么方法可以创建一个指向 mallocate-d 地址的指针,只存储 0 和 1,而不关心它们代表什么?缓冲方式适用于小文件,但对于大文件,我认为错误在于我试图将数千个字节存储为单个 int。
【解决方案3】:

也许看看open-source copy tool in C 会为您指明正确的方向。

【讨论】:

  • 对于许多认为这不是答案的人来说,如果我能弄清楚如何在 cmets 中嵌入链接,我很乐意将其转换为评论。跨度>
  • 很好发现。 Zach49899:看看复制功能。
【解决方案4】:

这是怎么做的:

选项 1:动态“数组”

嵌套级别: 0

// Variable Definition
char *cpArr;
FILE *fpSourceFile = fopen(<Your_Source_Path>, "rb");
FILE *fpTargetFile = fopen(<Your_Target_Path>, "wb");

// Code Section

// Get The Size Of bits Of The Source File
fseek(fpSourceFile, 0, SEEK_END); // Go To The End Of The File 
cpArr = (char *)malloc(sizeof(*cpArr) * ftell(fpSourceFile)); // Create An Array At That Size
fseek(fpSourceFile, 0, SEEK_SET); // Return The Cursor To The Start

// Read From The Source File - "Copy"
fread(&cpArr, sizeof(cpArr), 1, fpSourceFile);

// Write To The Target File - "Paste"
fwrite(&cpArr, sizeof(cpArr), 1, fpTargetFile);

// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);

// Free The Used Memory
free(cpArr);

选项 2:逐个字符

嵌套级别: 1

// Variable Definition
char cTemp;
FILE *fpSourceFile = fopen(<Your_Source_Path>, "rb");
FILE *fpTargetFile = fopen(<Your_Target_Path>, "wb");

// Code Section

// Read From The Source File - "Copy"
while(fread(&cTemp, 1, 1, fpSourceFile) == 1)
{
    // Write To The Target File - "Paste"
    fwrite(&cTemp, 1, 1, fpTargetFile);
}

// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    相关资源
    最近更新 更多