我有一个外部USB,NTFS格式的硬盘,其中包含许多文件,我最终需要将这些文件复制到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上的“应用程序”解决方案:
copy E:\externalDrivePath\targetFileName* anotherPath
。失败,出现0x7B错误。Windows Server 2008 R2上的“编程”解决方案:
我还涉及在OS X机器上安装此驱动器以运行副本,期望它将像Solaris那样为NTFS驱动器提供支持。但是,它无法将类似的错误消息复制到Windows - 我猜OS X的NTFS实现更像“Windows-like”?
如果这在Windows上是可解的,我觉得它要么需要一个非常低级的C函数来操作FILE本身,而不是根据它的字符串文件名“打开”它。不知道该怎么做。那个,或者我不知道哪些文件修复工具已经包含了这个功能。
如何实现我所描述的内容的任何替代方法或建议都将非常受欢迎。
答案 0 :(得分:1)
TLDR:尝试使用前缀为CreateFileW
且包含尾随回车符的unicode路径\\?\
。
\\?\
路径语法绕过了许多常用的验证规则,unicode扩展等,并允许长文件路径,甚至(危险地)允许文件名中的斜杠等字符。
考虑到这一点,我想象回车应该是相当微不足道的......
This page relating to long filenames有更多详情。相关部分引用如下
不需要对路径和文件名字符串执行任何Unicode规范化以供Windows文件I / O API函数使用,因为文件系统将路径和文件名视为不透明的WCHAR序列。在对相关Windows文件I / O API函数进行任何调用之外,应记住应用程序所需的任何规范化。
使用API创建目录时,指定的路径不能太长,以至于无法附加8.3文件名(即目录名不能超过MAX_PATH减去12)。 shell和文件系统有不同的要求。 可以使用Windows API创建一个shell用户界面无法正确解释的路径。
来自here
在较新的文件系统(例如NTFS,ex-FAT,UDFS和FAT32)上,Windows以Unicode格式将长文件名存储在磁盘上,这意味着始终保留原始长文件名。即使长文件名包含扩展字符,也不管在磁盘读取或写入操作期间处于活动状态的代码页,都是如此。即使文件系统不区分大小写,也会保留文件名的大小写......
答案 1 :(得分:0)
我在90年代中期在Windows 3.11上遇到了类似的问题。
我最终使用了来自C程序的rename
(在<stdio.h>
中声明)。
如果失败,您可以尝试低级C系统调用:open
,read
和write
将文件复制到新名称。
低级别通话通常会绕过用户友好的高级功能所施加的限制。