Jump to content

[Solved] FileCopy + PDFtk takes very long time


Recommended Posts

Hi,

I do recognize bad behaviour at this snippet:

#include <AutoItConstants.au3>
Global $g_sSD = @ScriptDir & "\"
Global $g_sBurstPath = $g_sSD & "Burst\"
DirCreate($g_sBurstPath)
Local $sFileName = "Test_mit_3_Seiten.pdf" ; any PDF with more than 1 page inside @ScriptDir

FileCopy($g_sSD & $sFileName, $g_sBurstPath & $sFileName, 1)
;~ Sleep(13000)
Local $hTimer = TimerInit()

ConsoleWrite("Start" & @CRLF)
_Burst($g_sBurstPath & $sFileName) ; bursts PDF into single pages
;~ While _FileInUse($g_sBurstPath & $sFileName)
;~  WEnd
ConsoleWrite("End: " & Round(TimerDiff($hTimer)) & "ms" & @CRLF)

Exit

Func _quotePath($sPath) ; because of possible "spaces" inside pathes
    $sPath = '"' & $sPath & '"'
    Return $sPath
EndFunc

Func _Burst($sFile)
    Local $sPDFtk = $g_sSD & "pdftk.exe" ; path to pdftk.exe (and libiconv2.dll)
    Local $sCurrWorkingDir = @WorkingDir
    FileChangeDir($g_sBurstPath) ; it has to change for reasons
    Local $iPID = Run(_quotePath($sPDFtk) & ' ' & _quotePath($sFile) & ' burst', "", @SW_SHOW, $STDOUT_CHILD + $STDERR_CHILD) ; @SW_SHOW just to see "PDFtk is working"
    Local $sOutput, $sError
    While 1
        $sOutput &= StdoutRead($iPID)
        $sError &= StderrRead($iPID)
        If @error Then ExitLoop
        Sleep(10)
    WEnd
    FileChangeDir($sCurrWorkingDir) ; back to normal
EndFunc

Func _FileInUse($sFilename) ; by Siao
    Local $aRet, $hFile
    $aRet = DllCall("Kernel32.dll", "hwnd", "CreateFile", _
                                    "str", $sFilename, _ ;lpFileName
                                    "dword", 0x80000000, _ ;dwDesiredAccess = GENERIC_READ
                                    "dword", 0, _ ;dwShareMode = DO NOT SHARE
                                    "dword", 0, _ ;lpSecurityAttributes = NULL
                                    "dword", 3, _ ;dwCreationDisposition = OPEN_EXISTING
                                    "dword", 128, _ ;dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL
                                    "hwnd", 0) ;hTemplateFile = NULL
    $hFile = $aRet[0]
    If $hFile = -1 Then ;INVALID_HANDLE_VALUE = -1
        $aRet = DllCall("Kernel32.dll", "int", "GetLastError")
        SetError($aRet[0])
        Return 1 ; file in use (@error contains system error code)
    Else
        ;close file handle
        DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
        Return 0 ; file not in use
    EndIf
EndFunc

This bursting took about 15000ms. If I activate line 8 "Sleep(13000)" then the bursting itself never needed more than 1000ms. Round about 13000ms delay is needed until bursting is acting very fast, otherwise needing about 15000ms.

Then I tested _FileInUse() instead of _Burst() w/o Sleep(13000). This runs in 3ms. It seemes to me that FileCopy() and Burst() are interacting in a way I can't see.

Any ideas? Regards, Conrad

P.S. You need pdftk.exe and libiconv2.dll at @ScriptDir. This you can get free here: https://www.pdflabs.com/tools/pdftk-server/ (I'm not sure whether I'm allowed to attach it here).

 

Edited by Simpel
english remarks at code + [Solved]
SciTE4AutoIt = 3.7.3.0   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win_10   Build = 19044   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE     H:\...\AutoIt3      H:\...\AutoIt3\Include     (H:\ = Network Drive)

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Link to comment
Share on other sites

Hi,

instead of FileCopy() I tested:

_WinAPI_CopyFileEx($g_sSD & $sFileName, $g_sBurstPath & $sFileName)

Same result. What is disturbing burst()?

Regards, Conrad

SciTE4AutoIt = 3.7.3.0   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win_10   Build = 19044   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE     H:\...\AutoIt3      H:\...\AutoIt3\Include     (H:\ = Network Drive)

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Link to comment
Share on other sites

Puh,

this is only happening on network drives. I copied all files for testing to local c: and it works fast as it should.

But I have no chance to let run this script in real life on a local disk.

Conrad

SciTE4AutoIt = 3.7.3.0   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win_10   Build = 19044   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE     H:\...\AutoIt3      H:\...\AutoIt3\Include     (H:\ = Network Drive)

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Link to comment
Share on other sites

Hello. I've tested with many pdfs and everything is working right about 250 ms for a 10 page pdf file. 

 

Saludos

Link to comment
Share on other sites

Hi,

even starting the script from an external usb drive is fast. So it seems to be bad only on network drives.

@Danyfirex: Did you try it at a network drive?

Conrad

SciTE4AutoIt = 3.7.3.0   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win_10   Build = 19044   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE     H:\...\AutoIt3      H:\...\AutoIt3\Include     (H:\ = Network Drive)

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Link to comment
Share on other sites

Link to comment
Share on other sites

Issue seems to be related to UNC paths. But I'm have no time to check deeply. Consider to do something like this.


 
;~ #RequireAdmin

;My paths
Local $sFileName="10page.pdf"
Local $sTempDir=@TempDir & "\TempPDFTK\"
Local $sPDFTKPath=@ScriptDir & "\pdftk.exe"
Local $sDirBurst=@ScriptDir & "\Busrt\"

;just for delete all
DirRemove($sDirBurst) ;delete  the burst out files path
DirRemove($sTempDir)  ;delete the temp folder

;Create Directories
If not FileExists($sTempDir) Then DirCreate($sTempDir)
If not FileExists($sDirBurst) Then DirCreate($sDirBurst)

;build path and run PDFTk.exe
Local $sFileFromPath=@ScriptDir & "\" & $sFileName
Local $sFileToPath=$sTempDir & $sFileName
FileCopy($sFileFromPath,$sFileToPath,1)
Local $iExitCode=RunWait(_quotePath($sPDFTKPath) & " " & _quotePath($sFileToPath) & ' burst',$sTempDir,@SW_SHOW)
FileMove($sTempDir & "*.*",$sDirBurst,1) ;move temp files to my burst directory
DirRemove($sTempDir) ;delete temp folder
Exit

Saludos

Link to comment
Share on other sites

  • 2 weeks later...

Hi.

Now I could implement the idea of @Danyfirex and use the @TempDir. That leads to a local drive.

Thanks for helping and regards, Conrad

SciTE4AutoIt = 3.7.3.0   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win_10   Build = 19044   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE     H:\...\AutoIt3      H:\...\AutoIt3\Include     (H:\ = Network Drive)

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...