ОАР>> А вот {PROP:Name} прекрасно возвращает текущее имя файла.
VS> Но вот у {PROP:Name} есть другая проблема (по крайней мере была на C5
VS> и ранних релизах C55) — инициализировать {PROP:Name} нужно перед
VS> каждой «глобальной» операцией типа OPEN/CREATE/BUILD etc
VS> Так что пользовать {PROP:Name} нужно тоже с осторожностью.
Да тут надо просто понимать, как этот механизм работает! А все довольно просто. Как всегда — дело в трейдовости файлов и в потоках, в которых эти файлы работают.
Для файлов с аттрибутом THREAD:
1. У файла ЯВНО НЕ задано имя через аттрибут NAME
ИЛИ задана константа:
MyFile FILE…,THREAD
или
MyFile FILE…,NAME(‘C:MyFile.tps’),THREAD
В этом случае, ПОСЛЕ ВХОДА в каждый новый поток, имена этих файлов ВСЕГДА будут сбрасываться в их исходное значение, т.е. «MyFile» или «C:MyFile.tps».
В ПРЕДЕЛАХ ОДНОГО потока имена таким файлам СПОКОЙНО можно менять через {PROP:Name} и дальше В ЭТОМ потоке эти имена самостоятельно уже НЕ ИЗМЕНЯТСЯ.
Также следует иметь в виду, что если имя такого файла было изменено через {PROP:Name} и был вызван новый поток, где используется этот файл, то после возврата из нового потока имя файла в данном потоке НЕ ИЗМЕНИТСЯ.
!!! Для нетрейдового файла такое изменение имени будет действительным для ВСЕЙ программы, в ЛЮБОМ потоке.
2. у файла, в качестве параметра аттрибута NAME задана переменная с аттрибутом THREAD:
MyFileName STRING(260),THREAD
MyFile FILE…,NAME(MyFileName),THREAD
Все работает абсолютно аналогично первому случаю за исключением того, что в новом потоке имя файла будет взято из переменной MyFileName, присвоенное ей В ЭТОМ-ЖЕ ПОТОКЕ.
3. у файла, в качестве параметра аттрибута NAME задана переменная без аттрибута THREAD:
MyFileName STRING(260)
MyFile FILE…,NAME(MyFileName),THREAD
Аналогично первому случаю, ТОЛЬКО в новом потоке имя файла будет взято из переменной MyFileName, присвоенное ей последний раз в ЛЮБОМ ПОТОКЕ.
Следует ОСОБО подчеркнуть — для трейдовых файлов, в пределах одного потока, изменение имени через свойство {PROP:Name} ОТМЕНЯЕТ возможность изменение
этого имени через переменную, заданную в NAME!!! Т.е., если трейдовый файл описан с переменной в аттрибуте NAME, то первое-же изменение его имени через {PROP:Name}
убивает указатель на переменную и дальше, в данном потоке, изменить имя этого файла можно будет ТОЛЬКО через то-же свойство {PROP:Name}!!!
Для обычных нетрейдовых файлов это будет действительно на протяжении выполнения ВСЕЙ программы.
Вот именно для такого случая и следует с осторожностью относится к изменению имени через свойство {PROP:Name}.
Что-же касается определения имени файла, то я больше предпочитаю использовать именно {PROP:Name}. Как я уже писал, в ПРЕДЕЛАХ одного потока это свойство ВСЕГДА возвращает РЕ АЛЬНОЕ имя файла. А оператор NAME() возвращает реальное имя файла
ТОЛЬКО пока файл открыт!
Простейший тест:
TFile FILE,DRIVER('TOPSPEED'),CREATE ... - message(Name(TFile)) ! вернет "TFILE" - message(TFile{PROP:Name}) ! вернет "TFILE" TFile{PROP:Name} = 'C:TEMPTFile.tps' - message(Name(TFile)) ! вернет "TFILE" - message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps" OPEN(TFile) ! или CREATE(TFile) - message(Name(TFile)) ! вернет "C:TEMPTFile.tps" - message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps" CLOSE(TFile) - message(Name(TFile)) ! вернет "TFILE" - message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"
Еще хуже дела обстоят, если используется переменная для имени:
TFile FILE,DRIVER(‘TOPSPEED’),CREATE,NAME(GLO:TFileName)
GLO:TFileName = 'D:DATATFile.tps' - message(Name(TFile)) ! вернет "D:DATATFile.tps" - message(TFile{PROP:Name}) ! вернет "D:DATATFile.tps" TFile{PROP:Name} = 'C:TEMPTFile.tps' - message(Name(TFile)) ! вернет "D:DATATFile.tps" !!! - message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps" OPEN(TFile) ! или CREATE(TFile) - message(Name(TFile)) ! вернет "C:TEMPTFile.tps" - message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps" CLOSE(TFile) - message(Name(TFile)) ! вернет "D:DATATFile.tps" !!! - message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"
!!! Не правда-ли — по крайней мере странно — файл на самом деле создан и лежит в «C:TEMPTFile.tps», а оператор NAME() продолжает нас уверять, что файл создан и лежит совсем в другом месте, а именно в «D:DATATFile.tps». Хотя буквально недавно, до закрытия файла, этот-же оператор вполне правильно определял месторасположение этого файла. Во истину — женская непостоянность!!!
Т.е. можно сделать очевидный вывод, что оператор NAME() для НЕОТКРЫТЫХ файлов ВСЕГДА возвращает значение имени из ЗАГОЛОВКА файла. А это — НЕПРАВИЛЬНО!!!
Дело в том, что первое ЛЮБОЕ действие с файлом приводит к созданию управляющей структуры файла и в дальнейшем (для трейдовых файлов — в пределах текущего трейда,
а для нетрейдовых файлов — в рамках всей программы) вся информация по этому файлу читается/пишеться через эту самую управляющую структуру!
А вот для открытых файлов оператор NAME() обращается уже непосредственно к этой самой управляющей структуре.
Опять-же, Агеев и Чушкин, может укажете разработчикам из SV на это расхождение как между методами работы свойства {PROP:Name} и оператора NAME() (которые, по идее, должны ВСЕГДА возвращать одно и то-же), так и на очевидную ошибку в работе оператора NAME() с неоткрытыми файлами?
Хотя, возможно я и не совсем прав?
Все таки иногда полезно, вероятно, получить для неоткрытого файла не его реальное текущее имя а значение переменной из его аттрибута NAME()?
Но, в таком случае, надо ОЧЕНЬ ЧЕТКО представлять себе логику работы как NAME() так и {PROP:Name}. А вот это как раз и не вполне четко прописано в доке.