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

MINGW64中带\\?\前缀的超长路径下_wstat失效问题

问题:MinGW编译下_wstat无法识别带\\?\前缀的长路径文件

问题描述

某C程序需用stat系列函数检查文件是否存在,因目标路径可能超过MAX_PATH(260字符),采用Windows官方推荐的\\?\长路径前缀,同时使用wchar_t*支持特殊字符。使用MSVC 19编译时,_wstat可正常找到\\?\D:\path\to\test.txt文件;但用MINGW64(gcc 12.2,Windows 11环境)编译相同程序时,_wstat调用失败,提示文件未找到。

复现步骤

  1. 编写main.c文件:
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <wchar.h>

int main(void) {
  //wchar_t* unicodeLongFileName = L"D:\\path\\to\\test.txt";  // 可正常运行
  wchar_t* unicodeLongFileName = L"\\\\?\\D:\\path\\to\\test.txt";  // 修正转义后的路径,MinGW下仍失效

  struct _stat statbuf;
  int res = _wstat(unicodeLongFileName, &statbuf);

  if (res != 0) {
    perror( "Problem getting information" );
    switch (errno)
    {
    case ENOENT:
      wprintf(L"File \n%ls\n not found.\n", unicodeLongFileName);
      break;
    case EINVAL:
      printf("Invalid parameter to _stat.\n");
      break;
    default:
      printf("Unexpected error in _stat.\n");
    }
    return -1;
  }

  wprintf(L"Found file \n%ls\n.\n", unicodeLongFileName);
  return 0;
}

注:原代码中字符串字面量存在转义错误,正确转义应为L"\\\\?\\D:\\path\\to\\test.txt",但即使修正后,MinGW下依然会出现问题。

  1. 编写CMakeLists.txt文件:
cmake_minimum_required(VERSION 3.20)
project(Test_wstat)
add_executable(Test_wstat main.c)
  1. 编译:
    • MSVC版本:
    cmake -S . -B build_msvc
    cmake --build build_msvc/ --config Release
    
    • MINGW64版本:
    cmake -S . -B build_mingw -G "MSYS Makefiles" -DCMAKE_C_COMPILER=gcc -Wno-dev
    make -C build_mingw/ all -Oline
    
  2. 运行:
    • 创建测试文件:touch /d/path/to/test.txt
    • MSVC编译程序:正常找到目标文件
    • MINGW64编译程序:提示文件未找到

原因分析

MinGW-w64的C运行时库(CRT)中,_wstat的实现基于POSIX兼容层的路径处理逻辑,并未完全适配Windows特有的\\?\长路径前缀;而MSVC的CRT直接调用Windows原生API,完全支持该前缀的解析。

解决方案

方案一:使用Windows原生API替代_wstat

直接调用Windows的GetFileAttributesW函数,该函数原生支持\\?\前缀,可直接判断文件是否存在:

#include <windows.h>
#include <wchar.h>
#include <stdio.h>

int main(void) {
  wchar_t* unicodeLongFileName = L"\\\\?\\D:\\path\\to\\test.txt";

  DWORD attr = GetFileAttributesW(unicodeLongFileName);
  if (attr == INVALID_FILE_ATTRIBUTES) {
    DWORD err = GetLastError();
    if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) {
      wprintf(L"File \n%ls\n not found.\n", unicodeLongFileName);
    } else {
      wprintf(L"Error accessing file: %lu\n", err);
    }
    return -1;
  }

  wprintf(L"Found file \n%ls\n.\n", unicodeLongFileName);
  // 若需获取更多文件信息,可使用GetFileInformationByHandle等API
  return 0;
}

编译时无需额外选项,MinGW可正常链接kernel32.lib。

方案二:让MinGW的_wstat支持长路径

若坚持使用_wstat,可尝试以下操作:

  1. 定义_WIN32_WINNT宏为0x0601(Windows 7及以上版本),启用长路径支持:
    在CMakeLists.txt中添加:
    target_compile_definitions(Test_wstat PRIVATE _WIN32_WINNT=0x0601)
    
  2. 使用_wstat64替代_wstat,MinGW的64位版本对长路径的支持更完善:
    将代码中的struct _stat改为struct _stat64,_wstat改为_wstat64。

不过该方案的兼容性不如直接调用Windows API可靠。


内容的提问来源于stack exchange,提问作者AnHeuermann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:39:54