【发布时间】:2023-03-17 06:15:02
【问题描述】:
我必须编写 C 代码来读取大文件。代码如下:
int read_from_file_open(char *filename,long size)
{
long read1=0;
int result=1;
int fd;
int check=0;
long *buffer=(long*) malloc(size * sizeof(int));
fd = open(filename, O_RDONLY|O_LARGEFILE);
if (fd == -1)
{
printf("\nFile Open Unsuccessful\n");
exit (0);;
}
long chunk=0;
lseek(fd,0,SEEK_SET);
printf("\nCurrent Position%d\n",lseek(fd,size,SEEK_SET));
while ( chunk < size )
{
printf ("the size of chunk read is %d\n",chunk);
if ( read(fd,buffer,1048576) == -1 )
{
result=0;
}
if (result == 0)
{
printf("\nRead Unsuccessful\n");
close(fd);
return(result);
}
chunk=chunk+1048576;
lseek(fd,chunk,SEEK_SET);
free(buffer);
}
printf("\nRead Successful\n");
close(fd);
return(result);
}
我这里面临的问题是,只要传递的参数(大小参数)小于264000000字节,似乎就可以读取。随着每个循环,我的块变量的大小都在增加。
当我通过264000000字节或更多时,读取失败,即:根据检查使用读取返回-1。
谁能指出为什么会这样?我在正常模式下使用 cc 编译,而不是使用 DD64。
【问题讨论】:
-
我可以看到您的代码存在一些严重问题。首先,您分配一个要读入的缓冲区,使用
size作为大小。然后,您使用固定大小读取缓冲区的信息,而不管您读入的缓冲区的分配大小。想想如果size小于 250k 会发生什么。其次,由于文件是新打开的,因此您无需寻找开头。第三,你然后寻找size,但是size是文件中的记录数还是字节数?在分配缓冲区时,您使用size的方式不同。 -
第四,释放循环内的缓冲区,但不要分配新的缓冲区。这意味着在第二次迭代中,它将读入未分配的内存。五、调用
read会自动推进文件中的位置,不需要每次都去寻找。第六,当您阅读时检查错误,但不检查文件结尾。read在文件末尾返回0。 -
最后,在读取大文件时,您不应该使用
read。使用例如mmap可能是更有效的解决方案,尤其是在您按顺序读取文件的情况下。 -
同意使用 mmap 读取大文件的建议。此外,还应考虑增加分页或交换内存大小,以避免内存分配错误。