【问题标题】:How can I validate if a file is name valid in Windows?如何验证文件名称在 Windows 中是否有效?
【发布时间】:2011-10-31 03:32:01
【问题描述】:

是否有一个 Windows API 函数可以传递一个字符串值,它会返回一个值,指示文件名是否有效?

我需要验证文件名是否有效,并且我正在寻找一种无需重新发明轮子的简单方法。我正在使用纯 C 语言,但针对的是 Win32 API。

如果没有内置这样的功能,我将如何编写自己的功能? Windows 是否有确定文件名有效性的通用算法或模式?

【问题讨论】:

  • 您要检查它是否正常吗?是否要检查文件是否存在?
  • @cnicutar,我想知道文件名是否有效,只有这个,文件存在我不感兴趣。
  • @Johnsyweb,我已经阅读了这个问题,并开始实现我自己的功能,但我很感兴趣有没有现成的解决方案来解决这个问题?
  • @akmal 你所说的有效是什么意思?

标签: c windows winapi path filenames


【解决方案1】:

如果您正在检查文件名是否在“文件可以这样命名吗?”的意义上有效。 :

不,没有直接检查的功能。您将不得不编写自己的函数。

但是,如果您知道什么是有效文件名(有效文件名现在包含以下任何内容:\ / : * ? " < > |),那么就不应该成为这样的问题。

您也许可以通过ctype.h 中的一些功能帮助您自己(使用它们您可以检查特定字符是否属于某些特定字符类):

http://www.cplusplus.com/reference/clibrary/cctype/

【讨论】:

  • 事情并没有那么简单,就像你描述的那样,对文件名有很多额外的限制,例如:保留文件名如(con,com1,com2,...),名称以空格或句号结尾,依此类推。
【解决方案2】:

此函数为您提供文件名的无效字符列表。由您来检查您的文件名是否不包含任何内容:

public static char[] Path.GetInvalidFileNameChars()

Docs here.

请注意,如果要验证目录名称,应使用GetInvalidPathChars()。

编辑:哎呀!抱歉,我以为你在 .NET 上。使用反射器,这个函数归结为:

'"', '<', '>', '|', 
'\0', '\x0001', '\x0002', '\x0003', '\x0004', '\x0005', '\x0006', 
'\a', '\b', '\t', '\n', '\v', '\f', '\r', 
'\x000e', '\x000f', '\x0010', '\x0011', '\x0012', '\x0013', '\x0014', '\x0015', 
'\x0016', '\x0017', '\x0018', '\x0019', '\x001a', '\x001b', '\x001c', '\x001d', 
'\x001e', '\x001f', 
':', '*', '?', '\\', '/'

注意,另外还有prn, con, com1, com2,... , lpt1, lpt2,...等保留名称

【讨论】:

  • 正如this answer 解释的那样,除了单个字符之外,还有更多需要考虑的因素。
  • 我不是在问我必须检查什么来验证文件名,我问的是为此目的准备好的功能。
  • @Serge - appTranslator, Naming Files, Paths, and Namespaces 我已经从这个来源阅读了有关命名文件的信息,这够了吗?
  • 我刚刚命名了一个文件 ☺.ini 没有问题 (\x0001)
  • @Orwellophile ☺ 没有代码 1; ALT 代码与字符代码不同
【解决方案3】:

问题并不那么简单,因为它取决于您认为的“有效文件名”。

与 UNC 路径一起使用的 Windows API 可以让您愉快地创建许多在正常路径中被视为无效的名称,因为前缀 \\?\ 您告诉 Windows API 只需将路径传递给文件系统驱动程序,不进行任何检查;文件系统本身通常并不真正关心它用作文件名,一旦他们知道某些字符串只是文件名(即路径/名称拆分已经完成),他们通常将其视为不透明的序列字符。

另一方面,如果您想安全起见,您应该根据您已经为 Win32 名称链接的MSDN document 指定的规则执行验证;我认为任何文件系统都不允许有比这些文件命名更严格的规则。另一方面,违反这些要求,虽然内核本身可以支持,但通常会让许多希望处理“传统”Win32 路径的“正常”应用程序头疼。

但是,在我看来,如果您必须立即创建文件,您可以做的最佳验证是尝试实际创建/打开文件,让操作系统为您完成这些工作,并准备好优雅地处理失败(GetLastError 应该返回 ERROR_BAD_PATHNAME)。这将检查您对创建此类文件的任何其他限制,例如您的应用程序具有适当的权限,该路径不在只读介质上,...

如果由于某种原因这是不可能的,你可能会喜欢 shell 函数PathCleanupSpec:提供请求的文件名和文件系统中必须创建它的目录,这个函数将删除所有无效的字符(我不确定保留的 DOS 名称,它们未在其文档中列出)使路径“可能有效”并通知您是否进行了任何修改(因此您也可以将其仅用于验证)。

请注意,此功能被标记为“在任何未来的 Windows 版本中可修改或可删除”,尽管 Microsoft 的政策通常是“任何进入公共标头的内容将永远保持公共状态”。

【讨论】:

  • +1 表示“尝试并检查失败”,而不是执行您自己的检查。这确实是测试 OP 问题等问题的唯一正确方法。
  • @Matteo Italia,创建和打开文件的有趣技巧,但在我的情况下这是不可能的,因为我正在使用光学媒体。
  • @akmal:在这种情况下,您还必须考虑 ISO 9660、Joliet、UDF 等的限制,具体取决于您要使用的扩展(假设您正在使用 CD或 DVD)。但我认为PathCleanupSpec 无论如何应该基本上可以工作。
  • @Matteo Italia,我尝试了“PathCleanupSpec”,我认为这不是解决方案,因为此功能仅用于清理输入文件/文件夹名称。
  • @SteveValliere:您输入的文件名实际上是有效的。您创建了一个带有 alternate data stream File*.ext 的 My 文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
相关资源
最近更新 更多