是否有办法让Qt 4.6
检查给定的QString
是否是当前操作系统上的有效文件名(或目录名)?我想检查名称是否有效,不表示文件存在。
示例:
// Some valid names
test
under_score
.dotted-name
// Some specific names
colon:name // valid under UNIX OSes, but not on Windows
what? // valid under UNIX OSes, but still not on Windows
我将如何实现这一目标?是否有一些Qt
内置函数?
我想避免创建一个空文件,但如果没有其他可靠的方法,我仍然希望看到如何以“干净”的方式进行。
非常感谢。
答案 0 :(得分:22)
这是我从Silje Johansen - 支持工程师 - Trolltech ASA(2008年3月)获得的答案
然而。包含区域设置和查找的复杂性 查询Linux / Unix上的文件系统的统一方法 功能几乎是不可能的。
然而,据我所知,我所知道的所有应用都忽略了这一点 问题
(读:他们不打算实施它)
Boost也没有解决问题,它们只给出了一些模糊的概念,即路径的最大长度,特别是如果你想要跨平台。据我所知,许多人尝试过并且未能解决这个问题(至少从理论上讲,在实践中,绝对有可能编写一个在大多数情况下创建有效文件名的程序。
如果您想自己实现这一点,可能值得考虑一些不那么明显的事情,例如:
包含无效字符的并发症
文件系统限制与操作系统和软件限制之间的差异。 Windows资源管理器,我认为是Windows操作系统的一部分,并不完全支持NTFS。包含':'和'?'等的文件可以很好地驻留在ntfs分区上,但资源管理器只会阻塞它们。除此之外,您可以安全地玩并使用Boost Filesystem中的建议。
路径长度的并发症
升级页面未完全解决的第二个问题是完整路径的长度。可能目前唯一可以确定的是没有OS /文件系统组合支持不确定的路径长度。但是,诸如“Windows最大路径限制为260个字符”之类的语句是错误的。 Windows中的unicode API允许您创建长达32,767 utf-16个字符的路径。我没有检查过,但是我想象资源管理器窒息同样专注,这会使这个功能对于拥有除你自己以外的任何用户的软件完全无用(另一方面你可能不希望你的软件合唱)。
存在一个名为PATH_MAX的旧变量,听起来很有希望,但问题是PATH_MAX simply isn't。
以结构性的说明结尾,这里有一些关于编写解决方案的可能方法的想法。
希望这有一些见解。
答案 1 :(得分:3)
我认为Qt没有内置函数,但如果Boost是一个选项,你可以使用Boost.Filesystem的name_check functions。
如果Boost不是一个选项,它在name_check函数上的页面仍然可以很好地概述在各种平台上检查的内容。
答案 2 :(得分:2)
基于User7116的答案:
How do I check if a given string is a legal / valid file name under Windows?
我放弃了懒惰 - 寻找优雅的解决方案,并对其进行了编码。我得到了:
bool isLegalFilePath(QString path)
{
// Anything following the raw filename prefix should be legal.
if (path.left(4)=="\\\\?\\")
return true;
// Windows filenames are not case sensitive.
path = path.toUpper();
// Trim the drive letter off
if (path[1]==':' && (path[0]>='A' && path[0]<='Z'))
path = path.right(path.length()-2);
QString illegal="<>:\"|?*";
foreach (const QChar& c, path)
{
// Check for control characters
if (c.toLatin1() > 0 && c.toLatin1() < 32)
return false;
// Check for illegal characters
if (illegal.contains(c))
return false;
}
// Check for device names in filenames
static QStringList devices;
if (!devices.count())
devices << "CON" << "PRN" << "AUX" << "NUL" << "COM0" << "COM1" << "COM2"
<< "COM3" << "COM4" << "COM5" << "COM6" << "COM7" << "COM8" << "COM9" << "LPT0"
<< "LPT1" << "LPT2" << "LPT3" << "LPT4" << "LPT5" << "LPT6" << "LPT7" << "LPT8"
<< "LPT9";
const QFileInfo fi(path);
const QString basename = fi.baseName();
foreach (const QString& s, devices)
if (basename == s)
return false;
// Check for trailing periods or spaces
if (path.right(1)=="." || path.right(1)==" ")
return false;
// Check for pathnames that are too long (disregarding raw pathnames)
if (path.length()>260)
return false;
// Exclude raw device names
if (path.left(4)=="\\\\.\\")
return false;
// Since we are checking for a filename, it mustn't be a directory
if (path.right(1)=="\\")
return false;
return true;
}
特点:
请注意,它不会检查以\\?\开头的文件名的长度,因为这不是一个严格的规则。另请注意,正如here所指出的,win32 API不会拒绝包含多个反斜杠和正斜杠的名称。
答案 3 :(得分:1)
难以在Windows上可靠地执行(某些奇怪的事情,例如名为“com”的文件仍然无效),您是否想要处理unicode或替代技巧以允许&gt; 260 char文件名。
这里已有一个很好的答案How do I check if a given string is a legal / valid file name under Windows?
答案 4 :(得分:1)
参见示例(来自Digia Qt Creator来源):https://qt.gitorious.org/qt-creator/qt-creator/source/4df7656394bc63088f67a0bae8733f400671d1b6:src/libs/utils/filenamevalidatinglineedit.cpp
答案 5 :(得分:0)
我只是创建一个简单的函数来验证平台的文件名,只需在字符串中搜索任何无效字符。不要以为Qt中有内置函数。您可以在函数内使用#ifdefs来确定您所在的平台。我会说足够干净。