Форум: "Основная";
Текущий архив: 2003.10.13;
Скачать: [xml.tar.bz2];
ВнизКак определить, содержит ли строка допустимый путь и имя файла Найти похожие ветки
← →
Vladimir (2003-10-02 10:56) [0]Подскажите простой путь, как определить содержит ли строка допустимый с точки зрения файловой системы путь и имя файла.
← →
VAleksey (2003-10-02 11:00) [1]if FileExists(MyFileStr) then
...
← →
Nikolay M. (2003-10-02 11:16) [2]Попробуй создать в проводнике файл с символами |, (, { - тебе сразу ругнутся, какие символы в названии допустимы, а какие - нет. Не скажу наверняка, что в разных версиях Windows символы будут идентичными.
← →
ZEE (2003-10-02 11:30) [3]> Nikolay M. © (02.10.03 11:16) [2]
> Попробуй создать в проводнике файл с символами |, (, { -
> тебе сразу ругнутся, какие символы в названии допустимы,
> а какие - нет. Не скажу наверняка, что в разных версиях
> Windows символы будут идентичными.
скобки (){}[] можн в имени файла писать
|\/?*: - эти символы нельзя (може правда и еще некоторые)
← →
Radionov Alexey (2003-10-02 11:33) [4]General rules for applications creating names for directories and files or processing names supplied by the user include the following:
· Use any character in the current code page for a name, but do not use a path separator, a character in the range 0 through 31, or any character explicitly disallowed by the file system. A name can contain characters in the extended character set (128-255).
· Use the backslash (\), the forward slash (/), or both to separate components in a path. No other character is acceptable as a path separator.
· Use a period (.) as a directory component in a path to represent the current directory.
· Use two consecutive periods (..) as a directory component in a path to represent the parent of the current directory.
· Use a period (.) to separate the base filename from the extension in a directory name or filename.
· Do not use the following characters in directory names or filenames, because they are reserved for Windows:
< > : " / \ |
· Do not use device names, such as aux, con, and prn, as filenames or directory names.
· Process a path as a null-terminated string. The maximum length for a path, including a trailing backslash, is given by MAX_PATH.
The wide (Unicode) versions of the CreateDirectory, FindFirstFile, GetFileAttributes, and SetFileAttributes functions permit paths that exceed the MAX_PATH length if the path has the "\\?\" or "\\?\UNC\" prefix. These prefixes direct the functions to turn off path parsing. Use the "\\?\" prefix with paths for local storage devices and the "\\?\UNC\" prefix with paths having the Universal Naming Convention format.
· Do not assume case sensitivity. Consider names such as OSCAR, Oscar, and oscar to be the same.
By following the rules listed in this section, an application can create valid names for files and directories regardless of the file system in use.
← →
Anatoly Podgoretsky (2003-10-02 11:34) [5]Это возможности не ОС, а файловой системы, которые подключаемые. То что допустимов в одной системе, ен пройдет в другой.
Простой путь и гварантированный, это попытаься создать файл и обработать исключение, предварительно убедиться, что такой файл не существует. Учитывать также права.
← →
Nikolay M. (2003-10-02 11:36) [6]
> ZEE © (02.10.03 11:30) [3]
Ну, я точно не помню, но почти наверняка - из написанных мной был хоть один (|). А лезть проверять лень помешала :)
← →
ZEE (2003-10-02 11:41) [7]кстати по теме - как-то видел один файл в имени которого почему-то был как раз недопустимый символ - так система его не позволяла ни удалить, ни переписать - интересно как он так назвался? наверно глюк какой пробежал...
← →
han_malign (2003-10-02 11:45) [8]>попытаься создать файл и обработать исключение
h:=CreateFile(PChar(FileName),0,0,nil,OPEN_EXISTING,0,0);
ValidName:=(h<>INVALID_HANDLE_VALUE)or(GetLastError<>ERROR_INVALID_NAME);
if(h<>INVALID_HANDLE_VALUE)then CloseHandle(h);
- исключение то здесь причем?
← →
Плохиш_ (2003-10-02 11:51) [9]Удалено модератором
← →
han_malign (2003-10-02 11:53) [10]Удалено модератором
← →
VAleksey (2003-10-02 11:55) [11]Удалено модератором
← →
Е-Моё имя (2003-10-02 11:55) [12]Удалено модератором
← →
han_malign (2003-10-02 11:58) [13]Удалено модератором
← →
Anatoly Podgoretsky (2003-10-02 12:09) [14]han_malign © (02.10.03 11:45) [8]
А CreateFile то ту при чем, почему бы не TFileStream.Create, ну не нравится исключения, используй функции, которые не вырабатывают исключение, с проверкой на ошибку. По сути тоже самое, создвть файл и убедиться, что создвлся (любым путем).
Или ты пос спорить, а суть так между прочим, или все таки суть интересует?
← →
Vladimir (2003-10-02 12:11) [15]Работает что- то типа
AssignFile(fFile, sFileName);
{$I-}
ReWrite(fFile);
{$I+}
if IOResult > 0 then MessageDlg("Not Create", mtInformation, [mbOK], 0);
Но если я хочу создавать этот файл много позже по ходу программы, то это не красиво. Например: пользователь задает в TEdit имя Log - файла, а потом жмет кнопку "создать". Желательно его предупредить сразу после ввода строки.
← →
Е-Моё имя (2003-10-02 12:23) [16]Удалено модератором
← →
Anatoly Podgoretsky (2003-10-02 12:31) [17]Vladimir (02.10.03 12:11) [15]
Вот когда нажмет и дашь ему сообщение, что недопустимое имя для лог файла и свои рекомендации
← →
han_malign (2003-10-02 12:51) [18]> ...почему бы не TFileStream.Create, ну не нравится исключения...
- исключение(сработавшее) - довольно длительная операция, и уж никак ни для штатного использования...
- тягу к TFileStream, не в контексте TPersistent, TWriter, TReader - я вообще не понимаю, но нравится - пусть. Только CreateFile - не выделяет дополнительную память под Instance, не тянет за собой Classes и позволяет "one touch" указать атрибуты доступа, хотя минус конечно есть - зависимость от платформы(OS)...
З.Ы. Со всем уважением, но - к месту, а чаще всего, не к месту, использованые громоздкие навороты - меня коробят...
>Vladimir (02.10.03 12:11) [15]
> ReWrite(fFile);
- см. han_malign © (02.10.03 11:45) [8], но теперь без "страшного" WinAPI
AssignFile(fFile, sFileName);
{$i-}
Reset(fFile);//отрыть существующий файл
{$i+}
res:=IOResult;//запоминаем, т.к. после вызова IOResult флаг ошибки очищается
ValidName:=res<>123{ERROR_INVALID_NAME};//The filename, directory name, or volume label syntax is incorrect.
if(res=0)//файл уже существует и открыт
then CloseFile(fFile);
WARNING: 123 - ERROR_INVALID_NAME - только под Windows, при переходе на другую систему, код ошибки необходимо будет уточнить...
> почему это от НАС?
- а я, к малознакомым людям, всегда на ВЫ обращаюсь(во всяком случае стараюсь)...
← →
Vladimir (2003-10-02 12:53) [19]Плюс есть такой нюанс:
FileExists() понимает имена типа aaa<aa.log как aaaaa.log, а
ReWrite() понимает имена типа aaa<aa.log как неправильные
← →
Anatoly Podgoretsky (2003-10-02 13:07) [20]han_malign © (02.10.03 12:51) [18]
Ты намекаешь, что он проверяет миллионы раз в секунду, особенно с учетом последнего замечания про пнопку, исключение займет ничтожную долю времени, по сравнению с самим созданием файла.
И в конце уоныов, если не понял, то суть состоит в том, что бы попытаться создать файл и узнать результат, а не в конкретных методах и функциях. Только создание файла позволит узнать можно ли создать файл с таким именем и почему его нельзя создать, остальное гадание на воде.
← →
Vladimir (2003-10-02 13:10) [21]> han_malign
Да, пожалуй Reset() лучше, лишних файлов не создает. Но все равно имеет побочные эффекты (переставляет указатель на начало).
А связка
if not FileExists() then Reset()
может не сработать в силу моего предыдущего замечания.
Хочется простого - по строке узнать правильный ли в ней путь.
← →
Amoeba (2003-10-02 13:30) [22]А если попробовать ф-ию ValidFileName из RxLib (модуль FileUtils)?
← →
han_malign (2003-10-02 13:53) [23]>Но все равно имеет побочные эффекты (переставляет указатель на начало).
- только если fFile - уже отрыт и открывается еще раз, и этот указатель действует только на этот конкретный fFile, если открыты другие, то это их никак не затронет.
З.Ы. Rewrite тоже "имеет побочные эффекты" - он уничтожает все, что в файле было записано до этого - " If an external file with the same name already exists, it is deleted and a new empty file is created in its place.".
З.З.Ы. Есть еще Append - но тоже "эффекты" - сдвигает указатель на конец файла..." Call Append to ensure that a file is opened with write-only access with the file pointer positioned at the end of the file."
← →
Rem (2003-10-02 14:05) [24]2 Vladimir (02.10.03 13:10) [21]
>> Хочется простого - по строке узнать правильный ли в ней путь.
function DirectoryExists(const Directory: string): Boolean;
← →
Rem (2003-10-02 14:12) [25]И почему бы не воспользоваться стандартным диалогом выбора файла?
Он тебе все проверит и возвратит корректное значение. Укажешь опции - и никаких мучений. Тем более, что не всякий пользователь захочет вручную прописывать в строке имя файла с папками.
Сделай справа от Edit кнопочку "Обзор" и запускай по нажатию диалог. А на Edit установи ReadOnly := true.
← →
Vladimir (2003-10-02 15:04) [26]>Amoeba (02.10.03 13:30) [22]
>А если попробовать ф-ию ValidFileName из RxLib (модуль FileUtils)?
ValidFileName, судя по тексту, проверяяет на наличие недопустимых символов, и имя файла c:\aa:aa.log - думаю, разрешит
← →
Amoeba (2003-10-02 15:26) [27]Посмотрите как реализована ф-ия FileExists в библиотеке JCL (модуль JclFileUtils). Наверное лучше всего использовать ее.
function FileExists(const FileName: string): Boolean;
begin
// Attempt to access the file, doesn"t matter how, using FileGetSize is as good as anything else.
Result := FileGetSize(FileName) <> -1;
end;
где:
function FileGetSize(const FileName: string): Integer;
var
SearchRec: TSearchRec;
OldMode: Cardinal;
begin
Result := -1;
OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
if FindFirst(FileName, faAnyFile, SearchRec) = 0 then
begin
Result := SearchRec.Size;
SysUtils.FindClose(SearchRec);
end;
finally
SetErrorMode(OldMode);
end;
end;
← →
Anatoly Podgoretsky (2003-10-02 15:56) [28]Vladimir (02.10.03 15:04) [26]
Для Fat15/Fat32 это недопустимое имя, для других систем вполне нормальное.
← →
Vladimir (2003-10-02 16:07) [29]FileExists в библиотеке JCL это кажется не про то, или я не понял.
Короче - способа без лазания на диск или Reset() - нет. Запасной вариант с TOpenDialog.
На этом предлагаю и порешить.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.10.13;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.013 c