我在 Windows 中工作,使用 vc++2010 和 MFC。
以下是我的代码:
CFile File;
TCHAR lpCause[1024];
CFileException eException;
CString strErrorMessage;
// a very long file path name means a file name over 255 characters
if (!File.Open(_T("a very long file path name"), CFile::modeCreate, &eException))
{
eException.GetErrorMessage(lpCause, 1024);
strErrorMessage = lpCause;
}
else
File.Close();
当我运行代码时,我收到错误消息:“一个很长的文件路径名包含一个不正确的路径”。
我的问题是:
- 如何修改我的代码以使其工作?
- 我了解到
CreateFile()
函数可以在文件路径的开头添加"\\\\?\"
,然后它将此限制扩展到32767
宽字符。如何在 MFC 中做同样的事情?
最佳答案
原因
在 CFile::Open()
的源代码中,有一个明确的检查路径长度是否超过 _MAX_PATH
:
if (lpszFileName != NULL && SUCCEEDED(StringCchLength(lpszFileName, _MAX_PATH, NULL)) )
如果超过 _MAX_PATH
,函数设置 pException->m_cause = CFileException::badPath
并返回 FALSE
。
即使是VS2017自带的MFC版本也是如此。
因此,绕过 _MAX_PATH
限制的标准技术,即在路径前加上 \\?\
将不起作用。
可能的解决方案
直接调用 CreateFileW()
以向其传递一个带有 \\?\
前缀的路径。使用接受HANDLE
的CFile
构造函数通过CFile
对象管理文件。 CFile
对象将取得句柄的所有权,因此您不得在句柄上调用 CloseHandle()
。
HANDLE hFile = CreateFileW( L"\\\\?\\a very long file path name", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, NULL );
if( hFile != INVALID_HANDLE_VALUE )
{
// Manage the handle using CFile
CFile file( hFile );
// Use the file...
// The CFile destructor closes the handle here.
}
else
{
DWORD err = GetLastError();
// TODO: do your error handling...
}
另一种可能性是从 CFile
派生一个类来覆盖 CFile::Open()
(它是虚拟的)。对于实现,复制/粘贴 MFC 源代码,但省略 _MAX_PATH
检查。对于大型项目,此类可以直接替代 CFile
以启用长路径。如果 \\?\
前缀不存在,您甚至可以在前面添加前缀(但这涉及更多,因为前缀还禁用从 Win32 路径到 NT- 的常规转换样式路径,如将 /
转换为 \
,解析点等)。
关于c++ - 当文件路径名超过 255 个字符时,如何在 Windows 中使用 MFC 创建文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49272809/