Проверьте, является ли строка допустимым именем файла с Qt
Есть ли способ с 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
?
Я бы хотел избежать создания пустого файла, но если нет другого надежного способа, я все равно хотел бы посмотреть, как это сделать "чистым" способом.
Большое спасибо.
Ответы
Ответ 1
Я не думаю, что Qt имеет встроенную функцию, но если Boost является опцией, вы можете использовать Boost.Filesystem name_check functions.
Если Boost не является опцией, его страница по функциям name_check по-прежнему является хорошим обзором того, что нужно проверить на разных платформах.
Ответ 2
Это ответ, который я получил от Silje Johansen - Support Engineer - Trolltech ASA (в марте 2008 года)
Однако. сложность включения языковых настроек и поиска единый способ запроса файловых систем в Linux/Unix об их функциональность практически невозможна.
Однако, насколько мне известно, все приложения, которые я знаю, игнорируют это проблема.
(читайте: они не собираются его реализовывать)
Boost также не решает проблему, они дают лишь некоторое неопределенное представление о максимальной длине путей, особенно если вы хотите быть кросс-платформой. Насколько я знаю, многие пытались и не смогли взломать эту проблему (по крайней мере теоретически, на практике, безусловно, можно написать программу, которая в большинстве случаев создает допустимые имена файлов.
Если вы хотите реализовать это самостоятельно, возможно, стоит рассмотреть несколько не сразу очевидных вещей, таких как:
Осложнения с недопустимыми символами
Разница между ограничениями файловой системы и ограничениями ОС и программного обеспечения. Проводник Windows, который я считаю частью ОС Windows, не полностью поддерживает NTFS, например. Файлы, содержащие ':' и '?' И т.д., Могут с радостью проживать на разделе ntfs, но Explorer просто задыхается от них. Кроме этого, вы можете играть в безопасное место и использовать рекомендации Boost Filesystem.
Осложнения с длиной пути
Вторая проблема, которая не полностью решена на странице повышения, - это длина полного пути. Вероятно, единственное, что наверняка на данный момент, состоит в том, что никакая комбинация OS/filesystem не поддерживает неопределенные длины пути. Однако такие утверждения, как "Максимальные пути Windows ограничены 260 символами", неверны. API Unicode из Windows позволяет вам создавать пути длиной до 32 767 символов utf-16. Я не проверял, но я полагаю, что Explorer удушал одинаково преданный, что сделало бы эту функцию совершенно бесполезной для программного обеспечения, имеющего других пользователей, кроме вас самих (с другой стороны, вы, возможно, предпочтете, чтобы ваше программное обеспечение не задыхалось в хоре).
Существует старая переменная, которая называется именем PATH_MAX, что кажется многообещающим, но проблема в том, что PATH_MAX просто не.
Чтобы закончить конструктивное замечание, вот несколько идей о возможных способах кодирования решения.
- Использование определяет, чтобы создавать разделы, специфичные для ОС. (Qt может помочь вам в этом)
- Используйте рекомендации, приведенные на странице повышения и документации по ОС и файловой системе, чтобы принять решение о своих незаконных символах.
- Для длины пути единственной работоспособной идеей, которая, как мне кажется, является двоичная древовидная пробная версия, использует метод обработки ошибок системного вызова для проверки допустимой длины пути. Это довольно отчужденно, но может быть единственной возможностью получения точных результатов в различных системах.
- Получите хорошую элегантную обработку ошибок.
Надеюсь, что это дало некоторые идеи.
Ответ 3
Трудно надежно работать с окнами (некоторые нечетные вещи, такие как файл с именем "com" по-прежнему недействительны), и вы хотите обрабатывать unicode или подталкивать, чтобы разрешить имя файлa > 260 char.
Здесь уже есть хороший ответ Как проверить, является ли данная строка легальным/допустимым именем файла под Windows?
Ответ 4
см. пример (из источников Digia Qt Creator) в: https://qt.gitorious.org/qt-creator/qt-creator/source/4df7656394bc63088f67a0bae8733f400671d1b6: SRC/ЛИЭС/Utils/filenamevalidatinglineedit.cpp
Ответ 5
Я бы просто создал простую функцию для проверки имени файла для платформы, которая просто ищет строку для любых недопустимых символов. Не думайте, что в Qt есть встроенная функция. Вы можете использовать #ifdefs внутри функции, чтобы определить, на какой платформе вы находитесь. Я бы сказал, достаточно чистый.
Ответ 6
На основе User7116 ответьте здесь:
Как проверить, является ли данная строка легальным/допустимым именем файла под 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() < 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;
}
Особенности:
- Вероятно, быстрее, чем использование регулярных выражений
- Проверяет наличие недопустимых символов и исключает имена устройств (обратите внимание, что "\" не является незаконным, поскольку оно может быть в именах путей)
- Позволяет записывать буквы букв
- Позволяет указать полные имена путей
- Разрешает имена сетевых путей
- Разрешает что-либо после \\?\(имена необработанных файлов)
- Отменяет все, начиная с \\.\(имена необработанных устройств)
- Запрещает имена, заканчивающиеся на "\" (т.е. имена каталогов)
- Запрещает имена длиной более 260 символов, начиная с \\?\
- Отменяет конечные пробелы и периоды
Обратите внимание, что он не проверяет длину имен файлов, начиная с \\? \, поскольку это не является жестким и быстрым. Также обратите внимание, как указано здесь, имена, содержащие несколько обратных косых черт и косых черт, НЕ отвергаются API win32.