调用hdfsRead读取HDFS文件出现短读,仅返回65536字节问题咨询
现象原因
hdfsRead接口本身遵循POSIX read调用语义,不保证一次性返回请求的全部字节数,只要返回值大于0就属于正常调用结果,出现短读是接口设计允许的行为。- 你调用
hdfsOpenFile时第4个参数(读取缓冲区大小)传入了0,会加载Hadoop客户端默认配置项dfs.client.read.buffer.size的值,你使用的Hadoop 2.x版本该参数默认值为65536字节(64KB),这是单次读取最大仅返回64KB的直接原因。 - 代码存在冗余参数问题:读文件时传入
O_CREAT标志完全不必要,虽然不会直接触发短读,但可能在目标路径不存在时意外创建空文件,掩盖路径错误的问题。
解决建议
- 优先通过循环调用
hdfsRead的方式读满期望字节数,适配接口原生的短读逻辑,参考实现如下:
void readtest() { hdfsFS fs = hdfsConnect("default", 0); const char* readPath = "/x/F1"; // 读文件去掉O_CREAT参数 hdfsFile readFile = hdfsOpenFile(fs, readPath, O_RDONLY, 0, 0, 0); if(!readFile) { fprintf(stderr, "Failed to open %s for reading!\n", readPath); exit(-1); } int buf_size = 1048576; char* buffer = malloc(buf_size); int total_read = 0; // 循环读取直到读满缓冲区或者到达文件末尾 while (total_read < buf_size) { int curr_read = hdfsRead(fs, readFile, buffer + total_read, buf_size - total_read); if (curr_read == 0) { // 已到文件末尾 break; } if (curr_read < 0) { fprintf(stderr, "Read file failed\n"); exit(-1); } total_read += curr_read; } printf("\n total read %d \n", total_read); free(buffer); hdfsCloseFile(fs, readFile); }
- 如果需要提升单次读取的最大长度,可以在
hdfsOpenFile时显式指定第4个参数为你需要的缓冲区大小,替代默认的64KB,示例:
// 显式指定读取缓冲区为1MiB hdfsFile readFile = hdfsOpenFile(fs, readPath, O_RDONLY, 1048576, 0, 0);
- 若要全局修改默认读取缓冲区大小,可以修改Hadoop客户端配置文件
core-site.xml,调整dfs.client.read.buffer.size参数为目标值,修改后重启应用即可生效。
内容的提问来源于stack exchange,提问作者CodeTry
相关产品推荐
相关产品推荐

