我正在处理以下代码:
枚举源目录和目标目录并生成{src
,dst
}对
...每对都发送到工作线程池
...执行工作,例如“将src
复制到dst
”
(所有这些都简化了很多)。
问题:
创建文件时,它还会获得一个短名称,该短名称可以与源目录中的另一个文件相同(名称冲突),从而导致多种效果(取决于操作顺序)。例如,复制两个文件my file
和MYFILE~1
可能会在目的地中生成2个或1个文件(取决于您的运气),内容可能已损坏(在后一种情况下)。
问题:
如何避免此类冲突引起的问题?拥有一个创建/打开忽略短文件的文件的功能会很好...
注释:
不能假设任何有关生成短名称的方式。各种系统采用不同的方案(请参见this)
即使您以顺序方式(一对一)运行这些作业,也需要按照短名称生成逻辑(未知)的顺序执行它们。加上这意味着在运行任何作业之前先在内存中加载和排序/等整个目录
源和目标都可能很大(可能有数百万个文件),(如果可能的话)我想避免将整个目录加载到内存中或枚举多次
无法关闭目标卷中的短名称生成,将其设为必需条件也不行(此外,将其关闭也不会删除现有的短名称)
应用程序仅限于Win32 API和NT API
编辑:我想到一般情况下,即使所有事情都在一个线程上发生,您也无法执行-仅仅是因为无论您选择哪种顺序,都会有一个短名称生成方案以及一组确保在处理过程中产生冲突的文件名。
如果这是正确的-系统实用程序如何复制文件?他们在复制完成后是否假设一些有关短名称的信息或执行“验证并修复差异”?
答案 0 :(得分:0)
问题基本上可以归结为以下内容:dst
绝不能通过shortname
打开。
例如(在NT API
的情况下,可以这样实现:
打开(NtCreateFile()
,不截断)dst
时,将FILE_OPEN_IF
用作CreateDisposition
成功检查IoStatusBlock::Information
是否已创建文件(FILE_CREATED
)
如果是,则无需执行任何操作(无法通过短名称创建文件)
如果否-通过NtQueryInformationFile(FileNameInformation)
NtCreateFile()
的名称不同(区分大小写!)–错误打开文件后,并行进程可能会立即重命名文件,但我会将其视为错误。
错误可能导致重试几次,然后导致严重失败(需要人为注意)。手动(或以编程方式)解决问题应该不太困难,因为冲突文件的名称由NtQueryInformationFile()
返回。
P.S。可以采取其他步骤来防止/减少碰撞。例如,如果已知短名称生成逻辑-dst
对象可以按特定顺序进行处理。
答案 1 :(得分:-2)
M。, 如果要禁用文件shorname,可以执行以下步骤: