[英]Malloc the size of file buffer base on an existing file
On my project, I need to copy the shared file into a directory which called share. 在我的项目中,我需要将共享文件复制到一个名为share的目录中。 My idea is to copy the contains of this file use fgets and fputs:
我的想法是使用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!!
However, the file buffer cannot be mallocated, the size of this file buffer is always 4. what happen? 但是,不能分配文件缓冲区,该文件缓冲区的大小始终为4.。会发生什么?
update: it seems have some misunderstanding. 更新:似乎有些误会。 the sizeof() if just for my to check whether there is any thing stored in the file buffer.
sizeof()是否仅用于检查文件缓冲区中是否存储了任何内容。 I do try strlen(fileBuff), and it gives me 1, always.
我确实尝试了strlen(fileBuff),它总是给我1,
This is wrong: sizeof(fileBuff)
. 这是错误的:
sizeof(fileBuff)
。 This will be the size of the pointer, which is 4 on your system. 这将是指针的大小,在您的系统上为4。
You cannot use sizeof
to "extract" the size of a block of memory returned by malloc()
. 您不能使用
sizeof
来“提取” malloc()
返回的malloc()
块的大小。 You can't use anything to extract that size, it's simply not possible in (standard) C. You need to use the size
value, ie the argument to malloc()
. 您不能使用任何东西来提取该大小,在(标准)C语言中根本不可能。您需要使用
size
值,即malloc()
的参数。
Also, ftell()
returns long
, not int
and both malloc()
and the various I/O calls can fail, which you need to take into account. 同样,
ftell()
返回long
,而不是int
并且malloc()
和各种I / O调用都可能失败,您需要考虑到这一点。
In my opinion, it's not a good idea to use a buffer the size of the file to do a simple copy; 我认为,使用文件大小的缓冲区进行简单复制不是一个好主意。 it's much better to use a "reasonable" buffer (whose exact optimal size depends on a lot of factors) and then do repeated read-write pairs in a loop until you've streamed through the entire file.
最好使用“合理的”缓冲区(其确切的最佳大小取决于很多因素),然后在循环中进行重复的读写对,直到流过整个文件为止。
UPDATE Further points about your code: 更新有关您的代码的其他要点:
strlen()
but the code shows sizeof
after the fread()
, too. strlen()
但是代码也在fread()
之后显示sizeof
。 sizeof
to "check" if there is anything in the buffer, this is not possible; sizeof
来“检查”缓冲区中是否有任何东西,这是不可能的; any expression with sizeof
is always evaluated at compile-time 1 , it cannot be used to check dynamic things like that. sizeof
表达式总是在编译时1进行求值,它不能用于检查像这样的动态事物。 And, again, you cannot use it to compute the size of a block of memory returned by malloc()
. malloc()
返回的malloc()
块的大小。 strlen()
on a buffer holding file data only works reliably if the file is binary and contains a '\\0' in its last position, otherwise you will have an unterminated string and strlen()
might invoke undefine behavior. strlen()
仅在文件为二进制文件且最后一个位置包含'\\ 0'时才能可靠地工作,否则,您将拥有一个不终止的字符串,并且strlen()
可能会调用未定义的行为。 malloc()
returns NULL
, which it will do if it fails to allocate the requested block of memory. malloc()
返回NULL
,如果它未能分配所请求的内存块,它将执行此操作。 1 Except for flexible arrays in C99, but let's ignore that. 1除了C99中的灵活数组外,让我们忽略它。
99 developers will now answer that you are taking the size of a pointer. 现在有99位开发人员将回答您正在使用指针大小。 I don't even have to look at the code.
我什至不必看代码。
The size of a pointer ( char *
) on your (32-bit) platform is always 4. 您的(32位)平台上的指针(
char *
)的大小始终为4。
You can't use sizeof
to determine how much memory has been allocated for a buffer. 您不能使用
sizeof
来确定为缓冲区分配了多少内存。
To check if the pointer has been allocated, check the return value of malloc()
: 要检查指针是否已分配,请检查
malloc()
的返回值:
fileBuff = malloc(size);
if (fileBuff == 0) {
fprintf(stderr, "Error allocating %d bytes.\n", size);
abort();
}
sizeof
is evaluated at compile time, since you are asking for sizeof
of filebuf
which is a char*
compiler calculates that it is 4 bytes (Since size of the pointer is 4 bytes ub your platform) and prints it. sizeof
是在编译时求值的,因为您要查询filebuf
sizeof
,而char*
编译器会计算它的大小为4个字节(因为指针的大小为平台的4个字节),然后打印出来。 The malloc
you did has nothing to do with sizeof
. 您执行的
malloc
与sizeof
无关。
Apart the improper use of sizeof() you may consider 2 more thoughts: 除了不正确地使用sizeof()之外,您还可以考虑以下两种想法:
If it's just to copy a file: Don't try to reinvent the wheel and just use the system() function and call the OS program designed for that ( cp on unix, copy on DOS/Windows). 如果只是复制文件:不要尝试重新发明轮子,而只需使用system()函数并调用为此目的设计的OS程序(Unix上为cp ,在DOS / Windows上为复制 )。
If it's for training purposes and you therefore insist to do it by yourself: Don't try to read in the whole file and then write it out again, but read and write chunk by chunk. 如果是出于培训目的,因此您坚持要自己做:不要尝试读入整个文件,然后再次将其写出,而是逐块读取和写入。 Using to big buffer sizes only results in rendering the CPU cache worthless.
使用大缓冲区只会导致CPU缓存变得毫无价值。 Usually matching the file system buffer size or a simple fraction of it is a goot chunk size, so the pseudo code should look like:
通常与文件系统缓冲区大小匹配或仅占其很小一部分的就是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
(and don't forget to check for I/O errors after each call to an I/O routine!) (并且不要忘记在每次调用I / O例程后检查I / O错误!)
And last note: Don't use fgets() unless you know for sure it's a always a plain text file. 最后一点:不要使用fgets(),除非您确定它始终是纯文本文件。 If you choose to use the fread()/fwrite() you are save, even if it's a binary file (and it's faster, too).
如果您选择使用fread()/ fwrite() ,即使它是二进制文件(而且速度也更快),您将被保存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.