Что нового

Путь вида C:\1\2\3\../../file.xxx

Andrey_A

Продвинутый
Сообщения
325
Репутация
68
Недавно извлекал текст из chm файла и для получения текста нужно было прочитать структуру распакованного файла и получить содержимое htm для извлечения...

К моему удивлению путь получился вида C:\tempppp\../../file.htm и он прочитался...

Возможно где-то уже было, но за 12 лет общения с Autoit такого не встречал ни в описании, ни в примерах.

Это глюк или фича?...

Я не проверял все функции, где присутствует путь, но ряд из них работает.

Вот простой пример того, о чём написал...

Может быть это кому-то поможет в работе, к примеру в "перемещении/копировании файлов на уровень вверх"

Код:
; Создание файла test.txt в 7-м уровне
$sFile='C:\xxYxxx\2\3\4\5\6\7\test.txt'
$sText='Line_1'&@CRLF&'Line_2'&@CRLF&'Line_3'&@CRLF&'Line_4'&@CRLF&'Line_5'&@CRLF&'Line_6'&@CRLF&'Line_7'&@CRLF&'Line_8'
_FileCreate($sFile,512+8+2,$sText)

; Копирование файла test.txt на уровень вверх и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../')
$iExists=FileExists('C:\xxYxxx\2\3\4\5\6\7\../test.txt')
MsgBox(4096,'$iExists','$iExists =>'&$iExists&'<=')
$sText_6=FileRead('C:\xxYxxx\2\3\4\5\6\7\../test.txt')
MsgBox(4096,'$sText_6','$sText_6 =>'&$sText_6&'<=')

; Копирование файла test.txt на 2 уровня вверх и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../../')
$sText_5=FileRead('C:\xxYxxx\2\3\4\5\6\7\../../test.txt')
MsgBox(4096,'$sText_5','$sText_5 =>'&$sText_5&'<=')

; Копирование файла test.txt на 3 уровня вверх в файл TEST-3.xxx и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../../../TEST-3.xxx')
$sText_4=FileRead('C:\xxYxxx\2\3\4\5\6\7\../../../TEST-3.xxx')
MsgBox(4096,'$sText_4','$sText_4 =>'&$sText_4&'<=')

; Копирование файла test.txt на 4 уровня вверх в файл TEST-4.yyy в создаваемую папку \AAA\BBB\ и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../../../../AAA\BBB\TEST-4.yyy',8)
$sText_3=FileRead('C:\xxYxxx\2\3\4\5\6\7\../../../../AAA\BBB\TEST-4.yyy')
MsgBox(4096,'$sText_3','$sText_3 =>'&$sText_3&'<=')


Func _FileCreate($sFile,$b,$sText)
  $hFile=FileOpen($sFile,$b)
  If $hFile=-1 Then Return
  $h=FileWrite($hFile,$sText)
  FileClose($hFile)
  Return $h=-1?0:1
EndFunc
 
Последнее редактирование:

IMStrelcov

CTPEJIbLLOB
Сообщения
259
Репутация
66
Недавно извлекал текст из chm файла и для получения текста нужно было прочитать структуру распакованного файла и получить содержимое htm для извлечения...

К моему удивлению путь получился вида C:\tempppp\../../file.htm и он прочитался...

Возможно где-то уже было, но за 12 лет общения с Autoit такого не встречал ни в описании, ни в примерах.

Это глюк или фича?...

Я не проверял все функции, где присутствует путь, но ряд из них работает.

Вот простой пример того, о чём написал...

Может быть это кому-то поможет в работе, к примеру в "перемещении/копировании файлов на уровень вверх"

Код:
; Создание файла test.txt в 7-м уровне
$sFile='C:\xxYxxx\2\3\4\5\6\7\test.txt'
$sText='Line_1'&@CRLF&'Line_2'&@CRLF&'Line_3'&@CRLF&'Line_4'&@CRLF&'Line_5'&@CRLF&'Line_6'&@CRLF&'Line_7'&@CRLF&'Line_8'
_FileCreate($sFile,512+8+2,$sText)

; Копирование файла test.txt на уровень вверх и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../')
$iExists=FileExists('C:\xxYxxx\2\3\4\5\6\7\../test.txt')
MsgBox(4096,'$iExists','$iExists =>'&$iExists&'<=')
$sText_6=FileRead('C:\xxYxxx\2\3\4\5\6\7\../test.txt')
MsgBox(4096,'$sText_6','$sText_6 =>'&$sText_6&'<=')

; Копирование файла test.txt на 2 уровня вверх и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../../')
$sText_5=FileRead('C:\xxYxxx\2\3\4\5\6\7\../../test.txt')
MsgBox(4096,'$sText_5','$sText_5 =>'&$sText_5&'<=')

; Копирование файла test.txt на 3 уровня вверх в файл TEST-3.xxx и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../../../TEST-3.xxx')
$sText_4=FileRead('C:\xxYxxx\2\3\4\5\6\7\../../../TEST-3.xxx')
MsgBox(4096,'$sText_4','$sText_4 =>'&$sText_4&'<=')

; Копирование файла test.txt на 4 уровня вверх в файл TEST-4.yyy в создаваемую папку \AAA\BBB\ и считывание
FileCopy($sFile,'C:\xxYxxx\2\3\4\5\6\7\../../../../AAA\BBB\TEST-4.yyy',8)
$sText_3=FileRead('C:\xxYxxx\2\3\4\5\6\7\../../../../AAA\BBB\TEST-4.yyy')
MsgBox(4096,'$sText_3','$sText_3 =>'&$sText_3&'<=')


Func _FileCreate($sFile,$b,$sText)
  $hFile=FileOpen($sFile,$b)
  If $hFile=-1 Then Return
  $h=FileWrite($hFile,$sText)
  FileClose($hFile)
  Return $h=-1?0:1
EndFunc
Если в пути идут ..\ - это каталог назад.
Если в начале пути .\ - это рабочий каталог.
Если в начале пути \ - это диск на котором лежит рабочий каталог.

Например:
скрипт/ехе лежит в D:\folder1\folder2
его с рабочий каталог при запуске C:\temp\Folder
то скрипт разберет путь:
..\papka как C:\temp\Folder\..\papka > C:\temp\papka
papka\..\file
как C:\temp\Folder\papka\..\file > C:\temp\Folder\file
.\papka
как C:\temp\Folder\papka
papka
как C:\temp\Folder\papka
\papka
как C:\papka

Т.е. это особенность винды, и если я понял правильно, все пути проверяются на полное имя, как это делает
_WinAPI_GetFullPathName ()
Если интересно вот мой аналог этой функции, с возможностью замены рабочего какалога (который используется для дополнения пути) на любой другой.
Код:
;###################################################################################################
; Описание:        создает полный абсолютный путь на основе относительного пути
;===================================================================================================
; Параметры:    $_sPath    = относительный путь к диску/папке/файлу,
;                            может начинаться как с диска:\ так и с имени папки/файла,
;                            или "\" (рабочий диск), или ".\" (рабочая папка)
;                            и "..\" (папка назад)
;                $_sBase    = базовый путь, который будет использоваться, для дополнения
;                            может быть или полный путь к каталогу или буква диска:
;===================================================================================================
; Результат:    возвращает полный абсолютный путь к диску/папке/файлу
;###################################################################################################
Func Path_GetFull_($_sPath, $_sBase = @WorkingDir)
   If Not StringRegExp($_sBase, '(^[[:alpha:]]:)') Then $_sBase = @WorkingDir
   $_sBase = StringRegExpReplace($_sBase, '([^\\])$', '$1\\')
   If StringRegExp($_sPath, '(^\\)') Then;добавить к началу базовый диск
      $_sPath = StringRegExpReplace($_sBase, '^(.:).*$', '$1')& $_sPath
   ElseIf Not StringRegExp($_sPath, '(^[[:alpha:]]:\\)') Then;добавить к началу базовый путь
      $_sPath = $_sBase& StringRegExpReplace($_sPath, '^(\.(\\|$)|.:\\?)', '')
   EndIf
   SetExtended(1)
   While @extended
      $_sPath = StringRegExpReplace($_sPath, '(?:(?:\\[^:\\]+\\)\.{2}(\\.*|$)|(.:\\)(?:\.{2}(\\|$))+)', '$1$2')
   WEnd
   Return StringRegExpReplace($_sPath, '([^\\])$', '$1\\')
EndFunc
 
Верх