繁体   English   中英

M基于现有文件分配文件缓冲区的大小

[英]Malloc the size of file buffer base on an existing file

在我的项目中,我需要将共享文件复制到一个名为share的目录中。 我的想法是使用fgets和fputs复制此文件的包含内容:

FILE *fp;
int size;
char *fileBuff

fseek(fp,0,SEEK_END );
size=ftell(fp);
printf("Size of %s: %d bytes.\n",path,size); // print correct size 
fileBuff=malloc(size); // mallocate the file buffer
printf("\nsize of file buffer is %d",sizeof(fileBuff)); //always print 4!!
while(!feof(fp)){
    fgets(fileBuff,size,fp); // put into file buffer

}
printf("\nsize of file buffer is %d",sizeof(fileBuff)); // also print 4!!

但是,不能分配文件缓冲区,该文件缓冲区的大小始终为4.。会发生什么?

更新:似乎有些误会。 sizeof()是否仅用于检查文件缓冲区中是否存储了任何内容。 我确实尝试了strlen(fileBuff),它总是给我1,

这是错误的: sizeof(fileBuff) 这将是指针的大小,在您的系统上为4。

您不能使用sizeof来“提取” malloc()返回的malloc()块的大小。 您不能使用任何东西来提取该大小,在(标准)C语言中根本不可能。您需要使用size值,即malloc()的参数。

同样, ftell()返回long ,而不是int并且malloc()和各种I / O调用都可能失败,您需要考虑到这一点。

我认为,使用文件大小的缓冲区进行简单复制不是一个好主意。 最好使用“合理的”缓冲区(其确切的最佳大小取决于很多因素),然后在循环中进行重复的读写对,直到流过整个文件为止。

更新有关您的代码的其他要点:

  1. 您谈论使用strlen()但是代码也在fread()之后显示sizeof
  2. 您谈论使用sizeof来“检查”缓冲区中是否有任何东西,这是不可能的; 任何带有sizeof表达式总是在编译时1进行求值,它不能用于检查像这样的动态事物。 同样,您不能使用它来计算malloc()返回的malloc()块的大小。
  3. 在保存文件数据的缓冲区上使用strlen()仅在文件为二进制文件且最后一个位置包含'\\ 0'时才能可靠地工作,否则,您将拥有一个不终止的字符串,并且strlen()可能会调用未定义的行为。
  4. 如我所说,您需要检查malloc()返回NULL ,如果它未能分配所请求的内存块,它将执行此操作。

1除了C99中的灵活数组外,让我们忽略它。

现在有99位开发人员将回答您正在使用指针大小。 我什至不必看代码。

您的(32位)平台上的指针( char * )的大小始终为4。

您不能使用sizeof来确定为缓冲区分配了多少内存。

要检查指针是否已分配,请检查malloc()的返回值:

fileBuff = malloc(size);

if (fileBuff == 0) {
   fprintf(stderr, "Error allocating %d bytes.\n", size);
   abort();
}

sizeof是在编译时求值的,因为您要查询filebuf sizeof ,而char*编译器会计算它的大小为4个字节(因为指针的大小为平台的4个字节),然后打印出来。 您执行的mallocsizeof无关。

除了不正确地使用sizeof()之外,您还可以考虑以下两种想法:

如果只是复制文件:不要尝试重新发明轮子,而只需使用system()函数并调用为此目的设计的OS程序(Unix上为cp ,在DOS / Windows上为复制 )。

如果是出于培训目的,因此您坚持要自己做:不要尝试读入整个文件,然后再次将其写出,而是逐块读取和写入。 使用大缓冲区只会导致CPU缓存变得毫无价值。 通常与文件系统缓冲区大小匹配或仅占其很小一部分的就是goot块大小,因此伪代码应类似于:

open input file for reading
open output file for writing
as long as read from input file BUFSIZE bytes and read bytes > 0
     do write read data to output file
close input file
close output file

(并且不要忘记在每次调用I / O例程后检查I / O错误!)

最后一点:不要使用fgets(),除非您确定它始终是纯文本文件。 如果您选择使用fread()/ fwrite() ,即使它是二进制文件(而且速度也更快),您将被保存。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM