C语言中含UTF-8字符的文件路径无法获取文件大小求助
解决含非ASCII字符路径的文件大小获取问题
问题根源
原代码通过wcstombs将宽字符路径转换为多字节字符串时,默认C locale无法识别土耳其语这类非ASCII字符,导致转换后的路径无效,fopen打开失败返回NULL,最终返回-1。setlocale会全局修改程序的locale配置,容易引发其他兼容性问题,不建议使用。你之前尝试的_wfopen参数有误:"w"是写模式(会清空或创建新文件),且ccs=UTF-8是设置文件内容的编码格式,和路径解析无关。
正确解决方案
方案1:使用宽字符版本_wfopen(C标准库方式)
直接用宽字符路径打开文件,跳过编码转换步骤,避免locale依赖:
long int getFileSize(const wchar_t* path) { long int res = -1; // 用只读二进制模式,避免文本模式换行符转换影响大小计算 FILE* fp = _wfopen(path, L"rb"); if (fp != NULL) { fseek(fp, 0L, SEEK_END); res = ftell(fp); fclose(fp); } return res; }
- 注意使用
L"rb"模式:二进制模式下ftell返回的是精确的文件字节数,文本模式可能因系统换行符差异导致大小计算偏差。
方案2:使用Windows API(更可靠,适合Windows平台)
如果是Windows环境,直接调用系统API获取文件大小,无需打开文件,效率更高且完全避免locale问题:
#include <windows.h> // 用long long支持超过2GB的大文件 long long getFileSize(const wchar_t* path) { HANDLE hFile = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile == INVALID_HANDLE_VALUE) { return -1; } LARGE_INTEGER fileSize; GetFileSizeEx(hFile, &fileSize); CloseHandle(hFile); return fileSize.QuadPart; }
- 该方法依赖Windows API,不涉及C标准库的locale设置,对含非ASCII字符的路径支持更稳定。
关键注意事项
- 处理含非ASCII字符的路径时,避免混用宽字符和多字节函数,始终使用宽字符版本的API(如
_wfopen、CreateFileW)。 - 如果需要兼容多平台,可考虑使用C11标准的
fopen_s配合宽字符参数,但Windows平台下_wfopen的兼容性和易用性更好。
内容的提问来源于stack exchange,提问作者fladon
相关产品推荐
相关产品推荐

