You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:15:29