3

我正在尝试编写一个 bittorrent 客户端。为了解析文件等,我需要将一个 torrent 文件读入内存。我注意到 fread 没有将整个文件读入我的缓冲区。经过进一步调查,似乎只要在文件中遇到下面显示的符号,fread 就会停止读取文件。在 FILE* 指针上调用 feof 函数返回 16,表示已到达文件末尾。无论符号放置在何处,都会发生这种情况。有人可以解释为什么会发生这种情况以及任何可能有效的解决方案。

该符号在下面突出显示:

在此处输入图像描述

这是执行读取操作的代码:

char *read_file(const char *file, long long *len){
struct stat st;
char *ret = NULL;
FILE *fp;

//store the size/length of the file
if(stat(file, &st)){
    return ret;
}
*len = st.st_size;

//open a stream to the specified file
fp = fopen(file, "r");
if(!fp){
    return ret;
}

//allocate space in the buffer for the file
ret = (char*)malloc(*len);
if(!ret){
    return NULL;
}

//Break down the call to fread into smaller chunks
//to account for a known bug which causes fread to
//behave strangely with large files

//Read the file into the buffer
//fread(ret, 1, *len, fp);
if(*len > 10000){
    char *retTemp = NULL;
    retTemp = ret;
    int remaining = *len;
    int read = 0, error = 0;
    while(remaining > 1000){
        read = fread(retTemp, 1, 1000, fp);
        if(read < 1000){
            error = feof(fp);
            if(error != 0){
                printf("Error: %d\n", error);
            }
        }
        retTemp += 1000;
        remaining -= 1000;
    }
    fread(retTemp, 1, remaining, fp);
} else {
    fread(ret, 1, *len, fp);
}

//cleanup by closing the file stream
fclose(fp);

return ret;
}

感谢您的时间 :)

4

3 回答 3

5

您的问题非常相关,因为我最近在上周工作的应用程序中遇到了这个问题!

该字符的 ASCII 值是十进制 26 (0x1A, \SUB, SUBSTITUTE )。这用于表示 CTRL+Z 键序列或文件结束标记。

更改您的fopen模式“在 [Text] 模式下,CTRL+Z 被解释为输入时的文件结尾字符。”)以在 Windows 上解决此问题:

fp = fopen(file, "rb"); /* b for 'binary', disables Text-mode translations */
于 2012-07-18T18:29:29.043 回答
4

您应该以二进制模式打开文件。某些平台在文本(默认)模式下,将某些字节解释为文件标记的物理结束。

于 2012-07-18T18:29:10.857 回答
4

您正在以文本而不是原始/二进制模式打开文件 - 箭头是 EOF 的 ASCII。为您的 fopen 调用指定“rb”而不仅仅是“r”。

于 2012-07-18T18:30:26.240 回答