Форум: "WinAPI";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
ВнизПроверка корректности имени файла Найти похожие ветки
← →
sadman (2004-09-21 11:13) [0]Подскажите пожалуйста, как программно проверить, подсунул ли пользователь программе корректное имя файла, а не "file:name/.ext".
Если нет в дельфи, то может в в WinAPI что-нить имеется?
← →
КаПиБаРа © (2004-09-21 11:16) [1]Попробуй создать такой файл.
================================
То, что само собой разумеется,
никогда не бывает на самом деле.
================================
← →
sadman (2004-09-21 11:23) [2]Например файл aux, lpt? =)
Хотелось бы формальную проверку.
← →
MBo © (2004-09-21 11:42) [3]http://www.codeproject.com/file/isvalidfilename.asp
или
function FileNameValidate(const AFileName: string): Boolean;
var
c: Char;
i: Integer;
begin
// Name length
if AFileName = "" then
begin
Result := False;
Exit;
end;
// Special characters
for i := 1 to Length(AFileName) do
begin
c := AFileName[i];
if (c in ["\", "/", ":", "*", "?", """, "<", ">", "|"]) then
begin
Result := False;
Exit;
end;
end;
// Reserved names
if (AFileName = "AUX") or (AFileName = "PRN")
or (AFileName = "CON") then
begin
Result := False;
Exit;
end;
// Complex reserved names
if (Copy(AFileName, 1, 3) = "COM") or (Copy(AFileName, 1, 3) = "LPT")
then
begin
Result := False;
Exit;
end;
Result := True;
end;
← →
Рамиль © (2004-09-21 11:47) [4]MBo © (21.09.04 11:42) [3]
Откуда такой код? Кошмар какой то...
← →
MBo © (2004-09-21 11:51) [5]>Рамиль © (21.09.04 11:47) [4]
:))
Поисковик нашел. С итальянского форума
В принципе - просто демонстрирует, что нужно проверять на недопустимые символы и зарезервированные имена.
← →
Рамиль © (2004-09-21 11:57) [6]MBo © (21.09.04 11:51) [5]
Так автор сабжа вставит его себе в программу в таком же виде, а потом скажет MBo такой код написал :)))
← →
TUser © (2004-09-21 12:03) [7][3]
Такой код пропустит, например, "." (а такого файла не бывает), ".." (и такого тоже). Наверное, самое правильное - это [1]
← →
sadman (2004-09-21 12:03) [8]Выглядит разумно, пуркуа бы и не юз ит =)
Странно все же, неужели WinAPI не содержит формальных средств проверки валидности имен и путей?
...кстати, тут придется еще дописывать path chekin" =)
← →
TUser © (2004-09-21 13:18) [9]
> Странно все же, неужели WinAPI не содержит формальных средств
> проверки валидности имен и путей?
Во всяком случае VCL корректность файлов не проверяет. Напр., TFileStream ничего специально не проверяет, а просто пытается создать файл. Если не получается - пишет ошибку.
← →
КаПиБаРа © (2004-09-21 13:30) [10]Ну будет имя файла правильное, а дискеты в дисководе нет... И какой смысл его проверять?
==========================================
Даже если вы точно знаете, что у вас мания преследования - это вовсе не значит,
что за вами никто не гонится.
==========================================
← →
sadman (2004-09-21 15:18) [11]Если дискеты нет, то это другая задача, не правда ли?
Не будем переходить из плоскости проверки корректности предаваемого в функцию параметра, на плоскость экспериментального создания файла. Если моя программа будет ориентироваться на возможность создания файла в пределах своей хардварной конфигурации, то грош цена ей. Ибо на другой машине дисковода вовсе не будет. А на третьей будет. А файл, лежащий в а:\log.txt все равно будет валидный. Isn"t?
← →
KSergey © (2004-09-21 15:29) [12]> [11] sadman (21.09.04 15:18)
Не верный подход.
Хотя, тут, наверное, надо различат 2 разные задачи:
а) необходимо ввести имя файла, который когда-то потом (в несвязной явно тут операции) будет создаватся. Это одно.
б) ввести имя файла и него что-то скинуть (явно тут же, по логике задачи). Это другое.
В первом случае - ну возможно есть смысл просто проверить, чтобы не колбасили явную ерунду, а там уже по месту ориентироваться.
Во втором же случае - ну ввел пользователь имя - да и ладно! Тут же пытаться писать, если что не так - орать матом. Какой тогда смысл дополнительно проверять? ОС сделает это самостоятельно. Я уж не говорю про сложные случае, например попытка заисис на некий сервер, не допускающий русских букв или длинных имен. Ну и что тут заранее проверишь? Разве что сделать узкоспециализированную задачу, для конкретной метсности? Да, можно, иногда оправдано, но не всегда верно.
← →
TUser © (2004-09-21 15:37) [13]Думаю, что если поискать, то наверняка есть хорошие готовые решения.
← →
KSergey © (2004-09-21 15:38) [14]> [13] TUser © (21.09.04 15:37)
А чем [3] плохое?? Что можно придумать принципиально лучше??
← →
TUser © (2004-09-21 15:53) [15]См. [7]
← →
KSergey © (2004-09-21 15:59) [16]> [15] TUser © (21.09.04 15:53)
Ну, напильником доработать ;) Впрочем, теперь понял о чем пожалуй речь
← →
sadman (2004-09-21 16:13) [17]Вобщем, после недолгого рысканья по MSDN выясняется, что явно не указано функции проверки валидности. Есть только General Rules по именованию файлов. Дальнейшие поиски показали, что каждая файловая система (от MS) подразумевает чуть ли не свой формат хранения (ограничения разные). Т.е. типовых решений быть в принципе, не может. Можно конкретизировать подход, описанный KSergey в [12] и написать только very stricted функцию (забыв про комфортные длинные имена и национальные буквы), проверяющую соответствие с General Rules. Ну, и уповать на то, что заказчик не даст по репе при повисании программы на какой-нить 95-й винде =)
...теперь понятно, почему виндовс виснет и марсоход мерьканский никак поймать не могут =)) Видимо, что изначальный подход построения виндов -- неформализованные проверки. Типа `авось запишеться` =) Не иначе, как Билли -- русский =))
← →
KSergey © (2004-09-21 16:15) [18]> Типа `авось запишеться`
Бред какой-то.
← →
KSergey © (2004-09-21 16:16) [19]> проверяющую соответствие с General Rules
Руки отрывать за такие писательства, если заранее в общем случае нет информации по конкретному месту эксплуатации, т.е., фактически, такое поведение не описано в ТЗ.
← →
sadman (2004-09-21 16:47) [20]Может и бред, я не спорю. Можете, канеш, и 03 позвонить.
Есть обычная задача: писать отчеты в файл. Где этот файл будет расположен -- непонятно (задается конкретным пользователем). Есть только исходная операционная система и предполагаемый пользователь. Пользователь может запускать данный модуль в любой из существующих версий виндов (в пределах допустимого пока еще есть и 95-е). Файловая система, естественно, предполагается, поддерживаемая операционной системой, в которой выполняется данный модуль (имеем FAT16, FAT32, NTFS, как минимум). При возникновении проблемы писания в лога нужно корректно указать пользователю (могущему быть древней бабушкой), что нужно сказать саппорту по телефону. А по возможности автоматически указать, что, мол, бабуля, ты скобочку на кой в имя файла запихала, а не доводить старушку до инфаркта Error-ами N xxxx .
Думаю, что на любом советском производстве с такой задачей сталкиваются. Если нет, то вам повезло. Если Вы пишете софт, каждый раз под юзера, то повезло юзеру.
Впрочем, у нас тут уже бесполезная перепалка. MS указывает, что есть General Rules и не более. В тех источниках, которые мне доступны.
← →
Anatoly Podgoretsky © (2004-09-21 16:56) [21]sadman (21.09.04 11:23) [2]
Нет смысла, надо просто писать и обрабатывать ошибку.
← →
Amoeba © (2004-09-21 17:06) [22]Если ничего не путаю, то кажись в RxLib была какая-то функция для проверки имен файлов на наличие недопустимых символов. Под рукой бибилиотеки сейчас нет, так что за точность информации не ручаюсь.
← →
Sandman25 © (2004-09-21 17:12) [23]По наводке [22] Amoeba © (21.09.04 17:06)
function ValidFileName(const FileName: string): Boolean;
const
MaxNameLen = 12; { file name and extension }
MaxExtLen = 4; { extension with point }
MaxPathLen = 79; { full file path in DOS }
var
Dir, Name, Ext: TFileName;
function HasAny(Str, SubStr: string): Boolean; near; assembler;
asm
PUSH DS
CLD
LDS SI,Str
LES DI,SubStr
INC DI
MOV DX,DI
XOR AH,AH
LODSB
MOV BX,AX
OR BX,BX
JZ @@2
MOV AL,ES:[DI-1]
XCHG AX,CX
@@1: PUSH CX
MOV DI,DX
LODSB
REPNE SCASB
POP CX
JE @@3
DEC BX
JNZ @@1
@@2: XOR AL,AL
JMP @@4
@@3: MOV AL,1
@@4: POP DS
end;
begin
Result := True;
Dir := Copy(ExtractFilePath(FileName), 1, MaxPathLen);
Name := Copy(ExtractFileName(FileName), 1, MaxNameLen);
Ext := Copy(ExtractFileExt(FileName), 1, MaxExtLen);
if (Dir + Name <> FileName) or HasAny(Name, ";,=+<>|"[] \") or
HasAny(Copy(Ext, 2, 255), ";,=+<>|"[] \.") then Result := False;
end;
← →
Anatoly Podgoretsky © (2004-09-21 17:16) [24]Amoeba © (21.09.04 17:06) [22]
Не рабочая
Sandman25 © (21.09.04 17:12) [23]
Не рабочая
← →
Юрий Зотов © (2004-09-21 17:48) [25]А просто MatchesMask с шаблоном "любой файл"?
← →
sadman (2004-09-21 18:15) [26]Юрий Зотов © (21.09.04 17:48) [25]
if (MatchesMask("file:name", "*")) then Edit1.Text:="yep" else Edit1.Text:="nope";
Увы.
← →
Defunct © (2004-09-21 19:17) [27]sadman (21.09.04 16:47) [20]
Храним отчет всегда в файле, к примеру, с именем report.txt, а пользователю даем возможность создать на него ярлык. Какие тут проблемы? В ТЗ описываете файл-отчет хранится там-то и там-то, ярлык создается так-то и так-то.
Пользователям конечного продукта должно быть все топорно документировано, а не так, что Вася поместил отчет хз где, а вам потом звонят и жалуются, что программа не ведет отчет.
← →
Defunct © (2004-09-21 19:22) [28]Sandman25 © (21.09.04 17:12) [23]
Это не будет работать.
LDS/LES не обслуживаются в Protected mode.
К тому же вопрос не о DOS names
← →
sadman (2004-09-22 09:39) [29]Defunct, мерси =)
Задача-то встречается и в других местах. Например там, где время на открывание файла с целью проверки валидности имени превышают... ну хотя бы секунды 3 (какое-нить защищенное соединение с авторизацией). Так что тут конкретное совершенно желание: проверить корректность имени, не прибегая к экспериментальным открытиям/созданиям файла.
Если данной функции нет, то нет. Большего я не хочу =)
← →
Anatoly Podgoretsky © (2004-09-22 09:59) [30]Желание понятно, но смысла нет.
Ну проверил ты, твоя функция подтвердила, а при реальном использовании получишь облом.
← →
sadman (2004-09-22 10:10) [31]Вероятность облома остается одинакова. Время, затраченное, на получение облома -- разнится в каждом случае =)
3 попытки * 3 секунды = 9 секунд до облома
<1 сек (3 проверки) + 3 секунды на проверку = ~3 секунды до облома
Пример условный, единицы времени выдуманы (не учитываются вероятности перегруза канала связи, таймауты на линиях и пр.), но задача вполне вероятна.
Впрочем, это уже теория пошла.
← →
Defunct © (2004-09-23 02:39) [32]sadman (22.09.04 10:10) [31]
Полнейшая чипуха. Создали файл - хорошо работаем сразу с ним. Не создали - "облом" отправляем обратным письмом. А в вашем случае дополнительно теряется время на проверку строки, итого время на проверку, потом время на создание - и приехали ваш долгожданный таймаут.
← →
Defunct © (2004-09-23 02:49) [33]sadman (22.09.04 10:10) [31]
PS: может у вас компьютер ZX Spectrum? что вы так переживаете за 3 сек? Современные машины выполняют 10^9 операций в секунду, скорость современных дисковых накопителей ~100MB/s, а вы тут рассказываете о каких-то обломах с созданием файла. Это все равно что переживать, не упадет ли Останкино под тяжестью гульки.
← →
Fay © (2004-09-23 03:03) [34]2Defunct © (23.09.04 02:49) [33]
>> скорость современных дисковых накопителей ~100MB/s
Это скорость чего?! Обмена с буфером? Попробуйте скопировать файл со скоростью 50Mb/s.
← →
Anatoly Podgoretsky © (2004-09-23 09:06) [35]Defunct © (23.09.04 02:49) [33]
А какая разница, какая скорость, все равно к времени проверки добавится время реального обращения, отсюда первая операция излишняя, ничего не дающая.
Fay © (23.09.04 03:03) [34]
У меня скорость обращения порядка 55 мб/сек, могу повысить до 110, надо только второй винчестер поставить.
Кроме того откуда копировать, с этого винчестера, с другого винчестера, с тем же контроллером или с отдельным контроллером, с сети? В любом случае время копирования это две операции чтение и запись.
← →
sadman (2004-09-23 15:30) [36]Defunct, а кто сказал, что я буду писать на супербыстрый накопитель, на не на удаленный ftp, через модем на 2400? =)
Вообще, конечно, забавно, что предполагается такой же умный пользователь, как программист, пишущий модуль =) У меня вон знакомый минут пять в ip-адресе запятую вместо точки поставил и искал баг.
← →
wicked © (2004-09-23 15:42) [37]хмм.... а если пробовать создать указанный файл в TEMP папке?...
или использовать регекспы для проверки правильности имени файла?... что то вродеExecRegExpr("^([^\\\/\|\:\*\"\<\>\?])+$", FileName)
....
и кстати, ":" является допустимым символом для имени файла - см. упоминания про NTFS stream на http://www.sysinternals.com
← →
Defunct © (2004-09-24 01:28) [38]sadman (23.09.04 15:30) [36]
> Defunct, а кто сказал, что я буду писать на супербыстрый накопитель, на не на удаленный ftp, через модем на 2400? =)
Ваш вопрос сказал.
Ибо на ftp совсем не такая форма записи, и некоторые ftp серверы не поддерживают русские символы в именах.
← →
GuAV © (2004-09-24 01:39) [39]
> Такой код пропустит, например, "." (а такого файла не бывает),
> ".." (и такого тоже).
А имя "..." является ?
← →
Defunct © (2004-09-24 01:47) [40]Anatoly Podgoretsky © (23.09.04 09:06) [35]
>А какая разница, какая скорость, все равно к времени проверки добавится время реального обращения, отсюда первая операция излишняя, ничего не дающая.
ХМ? Я разве предлагал проверять создание? Я предлагал создавать, и сразу с ним и работать, а не получилось создать - тогда вывести ошибку.
Я смотрю тут речь о сетевом доступе оказывается.
сервер должен проверять корректность имени, а не клиент, так как предусмотреть все стандарты невозможно, к тому же может быть просто такая обычная ситуация как нет доступа к ресурсу, прав не хватает, и что? спрашивается нафих проверяли корректность имени? Клиент может отбраковывать только грубые ошибки: звездочки, знаки вопроса в имени, а все остальное - работа сервера.
Страницы: 1 2 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.044 c