2013-07-01 47 views
1

我寫了一個函數,它從完整的路徑字符串獲取文件名。 但我寫的子程序需要花費太多時間(約4秒)才能執行。我試圖理解爲什麼。批處理文件功能需要太多的時間來執行

下面是批處理文件

@echo off 
set fullPath=\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt 
echo %fullPath% 
call:giveFileName "%fullPath%" finalName 
echo After Function call fileName: %finalName% Good Job 
goto:eof 

:giveFileName 
SETLOCAL 
set fileName=%~nX1 
::echo here is fileNmae %fileName% 
(ENDLOCAL&set %~2=%fileName% 
) 
goto:eof 

回答

3

我認爲,一個attaempt正在取得來定位\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt

自然,尋找該服務器是昂貴的。

如果你刪除\\server它是合理的光滑。

+1

+1,好主意。假設網絡性能合理,我懷疑如果服務器確實存在性能可能會好。 – dbenham

+0

@ peter-wright:是的,如果我用某個本地位置替換服務器位置(如c:\ Dir1),它實際上運行得很快。但我仍然無法理解爲什麼它很重要。腳本只是聲明一個字符串變量。而且,它並沒有指示尋找那個位置。 – Amit

+0

好,邏輯思維。唯一的問題似乎是它在實際中並不實際工作。這可能會歸結爲字符串如何被實際處理 - 也就是說,可能不是字符串,而是通過將其傳遞給某些OS函數(如INT 21H/60H)。任何人都會猜測操作系統在那裏做什麼。這實際上是一個明智的方法 - 你沒有不同的文件名驗證實現並行維護。在這種情況下,它會降低速度。當然,不是執行批量擴展的人做出的唯一不好的決定。 – Magoo

2

你可以試試這個(不提供任何擔保!):

@echo off 
set fullPath=\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt 
echo %fullPath% 
call:giveFileName "%fullPath%" finalName 
echo After Function call fileName: %finalName% Good Job 
goto:eof 

:giveFileName 
SETLOCAL 
set "fileName=%~1" 
FOR /f %%a IN ('cmd /c "ECHO %fileName:\=&echo(%"') DO set "fileName=%%a" 
(ENDLOCAL&set "%~2=%fileName%" 
) 
goto:eof 
1

與彼得·賴特的想法繼續,CMD是浪費時間尋找遠程\\server,它不存在。

您可以通過在另一個文件夾前添加路徑來防止CMD做到這一點。但是這隻適用於你想要的只是文件名和/或擴展名的情況。如果您需要驅動器和/或路徑,添加前綴會明顯損壞結果。

另外,如果您將作業放在與ENDLOCAL相同的行上,則不需要括號。但是因爲你所做的只是設置文件名,然後立即返回值,所以你甚至不需要中間值,所以你完全不需要SETLOCAL。

@echo off 
setlocal 
set "fullPath=\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt" 
echo %fullPath% 
call :giveFileName "%fullPath%" finalName 
echo After Function call fileName: %finalName% Good Job 
exit /b 

:giveFileName 
call :giveFileName2 "x\%~1" %2 
exit /b 

:giveFileName2 
set "%~2=%~nX1" 
exit /b 

通過使用FOR變量來獲取名稱和擴展名,可以使代碼更加高效。 FOR變量使用與CALL參數相同的擴展修飾符。

@echo off 
setlocal 
set "fullPath=\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt" 
echo %fullPath% 
call :giveFileName "%fullPath%" finalName 
echo After Function call fileName: %finalName% Good Job 
exit /b 

:giveFileName 
for %%F in ("x\%~1") do set "%2=%%~nxF" 

如果您不介意每次需要時重複FOR邏輯,則可以完全消除CALL。

@echo off 
setlocal 
set "fullPath=\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt" 
echo %fullPath% 
for %%F in ("x\%fullPath%") do set "finalName=%%~nxF" 
echo After FOR assignment: %finalName% Good Job 
exit /b 
1

在這種情況下,這似乎工作得更快。

@echo off 
set "fullPath=\\server\Dir1\Dir Number 2\Dir3\Dir4\abc.txt" 
echo %fullPath% 
call :giveFileName "%fullPath%" finalName 
echo After Function call fileName: "%finalName%" Good Job 
pause 
goto :eof 

:giveFileName 
SETLOCAL 
set "fileName=%~1" 
set "fileName=%filename:~2%" 
for /f "delims=" %%a in ("%filename%") do set "filename=%%~nxa" 
ENDLOCAL&set "%~2=%fileName%" 
goto:eof 
+0

當然,但你假設參數始終以\\開頭。例如,如果參數只是'file.ext',則您的建議失敗。在刪除第一個字符之前,您應該確認以\\開頭的值。我認爲插入像x \這樣的前綴要簡單得多。 – dbenham

+0

@dbenham該變量確實說'fullpath',所以我可以原諒去除前兩個字符。 :)雖然添加前綴更簡單,但你是對的。 – foxidrive