由于要读取整个文件,因此最好的方法是使缓冲区与文件大小一样大。随时调整缓冲区大小是没有意义的。这只会在没有充分理由的情况下损害性能。
您可以通过多种方式获取文件大小。快速而肮脏的方法是lseek()
到文件末尾:
// Get size.
off_t size = lseek(fd, 0, SEEK_END); // You should check for an error return in real code
// Seek back to the beginning.
lseek(fd, 0, SEEK_SET);
// Allocate enough to hold the whole contents plus a '\0' char.
char *buff = malloc(size + 1);
另一种方法是使用获取信息fstat()
:
struct stat fileStat;
fstat(fd, &fileStat); // Don't forget to check for an error return in real code
// Allocate enough to hold the whole contents plus a '\0' char.
char *buff = malloc(fileStat.st_size + 1);
要获取所有所需的类型和函数原型,请确保包含所需的标头:
#include <sys/stat.h> // For fstat()
#include <unistd.h> // For lseek()
注意read()
不会自动终止数据\0
。您需要手动执行此操作,这就是我们为缓冲区分配额外字符(大小+1)的原因。原因是已经有一个\0
你的情况中的字符纯粹是随机的。
当然,自从buf
现在是一个动态分配的数组,当你不再需要它时,不要忘记再次释放它:
free(buff);
但请注意,分配与要读入的文件一样大的缓冲区可能很危险。想象一下(无论是错误还是故意,都没关系)文件有几 GB 大。对于这种情况,最好设置最大允许大小。但是,如果您不希望有任何此类限制,那么您应该切换到另一种从文件读取的方法:mmap()
. With mmap()
,您可以将文件的一部分映射到内存。这样,文件有多大并不重要,因为您一次只能处理文件的一部分,从而控制内存使用。