【问题标题】:How to recurse down paths over 255 characters and read file attributes?如何递归超过 255 个字符的路径并读取文件属性?
【发布时间】:2013-06-03 18:45:54
【问题描述】:

Delphi:如何递归超过 255 个字符的路径并读取文件属性

我正在编写一个控制台应用程序,需要遍历路径远大于 255 个字符的目录结构,然后读取其中文件的属性。

从历史上看,我从 2006 年开始使用 Turbo Delphi 使用递归和 FindFirst,但这似乎跳过了超过 255 个字符的路径。

我可以将 FindFirst() 函数换成其他函数吗?还是我必须采取不同的方法?

【问题讨论】:

  • 这是Delphi - How to check if a file exists path over 255 characters 的副本,但它询问的是FileExists 而不是属性。不过,基本问题和它的答案是一样的。
  • @KenWhite 这个问题与属性无关。它们可以从WIN32_FIND_DATAW 结构中读出。问题仅仅是对 FindFirstFile 的调用,它需要摆脱 260 个字符的限制。
  • @David:您对上一个问题的回答也涵盖了所有这些内容,包括Naming Files 链接和提到的 A/W 版本。这有什么不同?
  • @KenWhite 我不认为这有很大不同。主要区别在于,在另一个问题中,它是一个简单的前置 `\\?` 的情况。但是在这里您需要这样做,并使用 Win32 查找文件 API 而不是 RTL 包装器。这是一个额外的复杂层。所以我想强调前缀的确切位置,并指出结构中路径中的 260 个限制不是问题,因为名称是相对于其包含目录的名称。所以,它几乎相同,需要相同的知识,基本上相同的解决方案,但我认为答案会有所帮助。
  • @Ken 另一个问题没有谈到 FindFirst,所以我在这里的大部分答案都不相关。

标签: delphi winapi delphi-2006


【解决方案1】:

如果您在文件名前加上 \\?\,那么您将启用扩展长度路径解析,从而摆脱 260 个字符的路径长度限制。

为了使这个前缀起作用,您需要调用 Win32 API 函数的 Unicode 版本。因此,如果您使用的是 Unicode Delphi,那么这就是您需要做的所有事情。但是由于您使用的是 Unicode 之前的 Delphi,您必须推出您自己的 FindFirst 版本,它调用 API 函数的 Unicode 版本。您将调用 FindFirstFileWFindNextFileWFindClose 并使用 Unicode 版本的结构 WIN32_FIND_DATAW

MSDN 上详细讨论了这些问题:Naming Files, Paths, and Namespaces

在您的特定情况下,FindFirstFileW 的文档将问题称为如下:

在此函数的 ANSI 版本中,名称仅限于 MAX_PATH 个字符。要将此限制扩展到 32,767 个宽字符,请调用函数的 Unicode 版本并在路径前添加“\?\”。

请注意,WIN32_FIND_DATAW 中的两个文件名字段的长度限制为 260 个字符。这很好,因为它们只包含名称的相对部分,即相对于包含目录的对象名称。调用FindFirstFileW时只需使用\\?\前缀即可。

为了使用此 API 的 Unicode 版本,您将为FindFirstFileWlpFileName 参数使用WideString,并使用PWideChar(FileName) 传递它。

var
  FileName: WideString;
....
// initialise FileName, this will happen in your recursion
FindHandle := FindFirstFileW(PWideChar(FileName), FindData);

至于文件属性,可以在每次迭代时从WIN32_FIND_DATAW 结构中读出。你的那部分代码不需要改变。您唯一需要修复的是在对FindFirstFileW 的初始调用中解析 >260 字符。其他一切都正常进行。

【讨论】:

  • 当我读到它时,这是一个问题,要么围绕 unicode 函数为旧版本的 Delphi 包装我自己的函数,要么使用更新的“unicode”版本。如果我做了后者并重新编译,那会起作用吗?
  • 如果您在 Unicode Delphi 中重新编译,并添加了魔术前缀,那么您将得到您正在寻找的结果。那是因为FindFirst 将您的Path 参数传递给FindFirstFile,并且您在Unicode Delphi 中获得了Unicode 版本。
猜你喜欢
  • 2013-07-15
  • 2013-05-28
  • 2012-06-01
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多