繁体   English   中英

在Windows上使用文件名回车处理文件

[英]Handling files with carriage return in filename on Windows

我有一个外部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上的“应用程序”解决方案:

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

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 \\ n”。 调用再次失败,出现0x7B错误。

我还涉及在OS X机器上安装此驱动器以运行副本,期望它将像Solaris那样为NTFS驱动器提供支持。 但是,它无法将类似的错误消息复制到Windows - 我猜OS X的NTFS实现更像“Windows-like”?

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

任何替代方法或建议如何实现我所描述的将是最受欢迎的。

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

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

鉴于此,我认为回车应该是相当微不足道的...

这个与长文件名相关的页面有更多细节。 相关部分引用如下

无需对路径和文件名字符串执行任何Unicode规范化以供Windows文件I / O API函数使用,因为文件系统将路径和文件名视为不透明的WCHAR序列。 在对相关Windows文件I / O API函数进行任何调用之外,应记住应用程序所需的任何规范化。

使用API​​创建目录时,指定的路径不能太长,以至于无法附加8.3文件名(即目录名不能超过MAX_PATH减去12)。 shell和文件系统有不同的要求。 可以使用Windows API创建一个shell用户界面无法正确解释的路径。

这里开始

在较新的文件系统(如NTFS,ex-FAT,UDFS和FAT32)上,Windows以Unicode格式将长文件名存储在磁盘上,这意味着始终保留原始长文件名。 即使长文件名包含扩展字符,也不管在磁盘读取或写入操作期间处于活动状态的代码页,都是如此。 即使文件系统不区分大小写,也会保留文件名的大小写...

在Windows 3.11上,我在90年代中期遇到过类似的问题。

我最终使用了C程序的rename (在<stdio.h>声明)。

如果失败,您可以尝试低级C系统调用: openreadwrite将文件复制到新名称。

低级别呼叫通常会绕过用户友好的高级功能所施加的限制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM