代码之家  ›  专栏  ›  技术社区  ›  topcat

文件流缓冲区是如何工作的?

  •  1
  • topcat  · 技术社区  · 6 年前

    我理解 fopen() 打开文件并为该文件的读写操作创建缓冲区。 fopen() 返回该缓冲区的指针。

    所以我的问题是,在下面的代码中 _copy 功能体有一个 temp 要在 fread() fwrite() . 为什么我不能直接从一个缓冲区转移到另一个缓冲区?

    /* example: copyfile.exe xxxxx.txt   zzzzzz.txt */
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BUFF 8192
    void _copy(FILE *source, FILE *destination);
    
    int main(int argc, char *argv[])
    {
        FILE *fp1, *fp2;  // fp1 source file pointer// fp2 copied file pointer 
    
        if (argc !=3 )           //command line must have 3 arguments
        {
            fprintf(stderr, "Usage: %s (source file) (copy file)\n", argv[0][0]);
            exit(EXIT_FAILURE);
        }
    
        if ((fp1 = fopen(argv[1], "rb")) == NULL)    //Opening source file
        {
            fprintf(stderr, "Could not open %s\n",argv[1]);
            exit(EXIT_FAILURE);
        }
        if((fp2 = fopen(argv[2], "ab+")) == NULL)  //Opening destination file
        {
            fprintf(stderr, "could not create %s \n",argv[2]);
            exit(EXIT_FAILURE);
        }
        if( setvbuf(fp1,NULL, _IOFBF, BUFF) != 0) //Setting buffer for source file
        {
            fputs("Can't create output buffer\n", stderr);
            exit(EXIT_FAILURE);
        }
        if( setvbuf(fp2,NULL, _IOFBF, BUFF) != 0) //Setting buffer for destination file
        {
            fputs("Can't create input buffer\n", stderr);
            exit(EXIT_FAILURE);
        }
    
    
        _copy(fp1, fp2);  
        if (ferror(fp1)!=0)
            fprintf(stderr, "Error reading file %s\n", argv[1]);
        if(ferror(fp2)!=0)
            fprintf(stderr, "Error writing file %s\n",argv[2]);
        printf("Done coping %s (source) to %s (destination) \n",argv[1], argv[2]);
        fclose(fp1);
        fclose(fp2);
        return (0);
    }
    
    void _copy(FILE  *source, FILE *destination)
    {
        size_t bytes;
        static char temp[BUFF];
    
        while((bytes = fread(temp,sizeof(char),BUFF,source))>0)
            fwrite(temp,sizeof(char),bytes,destination);
    }
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Serge Ballesta    6 年前

    不能在另一个文件*中使用来自文件*的基础缓冲区。正如在注释中告诉您的,FILE*是一个不透明的指针。但通过强制两个文件处于非缓冲模式,可以避免在缓冲区之间复制数据的开销:

    setbuf(fp, NULL);   // cause the stream to be unbuffered