gpt4 book ai didi

c++ - 在 Windows 上处理文件名中带有回车符的文件

转载 作者:可可西里 更新时间:2023-11-01 13:47:00 32 4
gpt4 key购买 nike

我有一个 NTFS 格式的外部 USB 硬盘驱动器,其中包含许多文件,我需要最终将这些文件复制到 Windows Server 2008 R2 机器上的驱动器上。

驱动器上的文件是由安装在 Solaris 上的驱动器运行的脚本放置在那里的。进行此复制的用户粗心并在 Windows 机器上编辑了他们的复制脚本,导致 shell 脚本行如下:

cp /sourceDir/sourceFileName /externalDrivePath/targetFileName\r\n

因此,外部驱动器上的文件在其文件名中有尾随回车符。标准 Windows 复制实用程序(copy、xcopy、robocopy)无法复制这些文件,并出现错误 0x7B/123:“文件名、目录名或卷标语法不正确。”

我已经测试过,并且相当确定如果我将驱动器重新安装到 Linux 机器上,我应该能够使用以下命令修复文件:

mv /externalDrive/targetFileName\r /externalDrivePath/targetFileName\n

但是,我无法立即访问 Linux 机器。

到目前为止,我已尝试修复/移动这些文件:

Windows Server 2008 R2 上的“应用程序”解决方案:

  1. 在 Windows 资源管理器中重命名文件 -- 由于文件量太大,这将是不可行的解决方案,但无论如何它都行不通。
  2. 通配符模式匹配 cmd 提示符下的文件名,例如复制 E:\externalDrivePath\targetFileName* anotherPath。失败并出现 0x7B 错误。
  3. 使用 8.3(短)文件名从 cmd 提示复制文件。根据 dir/x
  4. 的输出,有问题的文件没有短名称

Windows Server 2008 R2 上的“编程”解决方案:

  1. 使用 Python/Java 复制/重命名文件:任何打开/复制回车文件的尝试都会抛出异常,追溯到相同的 0x7B Windows 错误。
  2. 使用 Windows C“CopyFile”API 复制文件:失败并出现 0x7B 错误。在这里,我使用 FindNextFile API 找到了文件,并将该源路径传递给 CopyFile,但操作系统仍然无法复制文件。
  3. 使用 fopen、ofstream 等在 C 中编写我自己的文件复制函数。fopen 调用再次失败,返回 0x7B。
  4. 使用 C++ boost::filesystem API 复制文件:失败并出现 0x7B 错误。同样,使用 boost::filesystem::directory_iterator 找到文件并将找到的文件的路径传递给 boost::filesystem::copy_file()
  5. 提供 Win32 API CopyFile/MoveFile 的文件路径为“\?\E:\externalDrivePath\targetFileName\r”。调用再次失败,出现 0x7B 错误。

我还尝试在 OS X 机器上安装这个驱动器来运行拷贝,希望它能像 Solaris 那样提供对 NTFS 驱动器的支持。但是,它无法将类似的错误消息复制到 Windows——我猜 OS X 的 NTFS 实现更“类似于 Windows”?

如果这在 Windows 上是可解决的,我觉得它要么需要一个非常低级的 C 函数来操作 FILE 本身,而不是根据其字符串文件名“打开”它。不知道该怎么做。那个,或者一些我不知道的文件修复实用程序已经包含了这个功能。

对于如何实现我所描述的内容的任何替代方法或建议,我们将不胜感激。

最佳答案

TLDR:尝试使用 CreateFileW\\?\ 为前缀并包含尾随回车符的 unicode 路径。

\\?\ 路径语法绕过了很多常用的验证规则、unicode 扩展等,并允许长文件路径,甚至(危险地)允许文件名中包含斜杠等字符。

鉴于此,我认为回车应该很容易处理...

This page relating to long filenames有更多细节。相关部分引用如下

There is no need to perform any Unicode normalization on path and file name strings for use by the Windows file I/O API functions because the file system treats path and file names as an opaque sequence of WCHARs. Any normalization that your application requires should be performed with this in mind, external of any calls to related Windows file I/O API functions.

When using an API to create a directory, the specified path cannot be so long that you cannot append an 8.3 file name (that is, the directory name cannot exceed MAX_PATH minus 12).The shell and the file system have different requirements. It is possible to create a path with the Windows API that the shell user interface is not able to interpret properly.

来自here

On newer file systems, such as NTFS, ex-FAT, UDFS, and FAT32, Windows stores the long file names on disk in Unicode, which means that the original long file name is always preserved. This is true even if a long file name contains extended characters and regardless of the code page that is active during a disk read or write operation. The case of the file name is preserved, even when the file system is not case-sensitive ...

关于c++ - 在 Windows 上处理文件名中带有回车符的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21571999/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com