2016-12-22 2 views
1

Я написал небольшой proc, чтобы рекурсивно удалить% TEMP% dir в окнах, которые были довольно громоздкими по каждому циклу выполнения. Но, похоже, он работал медленно - быстрее было вручную выбирать разные папки внутри пути% TEMP% и запускать удаление на нем. Есть ли возможность использовать потоки/pthreads для одновременного удаления папок. Или альтернативное решение. Нужна помощь в следующем коде.Tcl: удалять каталог рекурсивно - улучшая производительность с помощью потоков

proc DirRecursion {dir args} {  
    set options(-files) "" 
    set options(-fileTypesFilter) "ALL" 
    array set options $args 
    upvar $options(-files) lf 
    #Performing action deletion on files for dir $dir ... please be patient as this might take some time 
    if ![catch { append lf " [glob -directory $dir -type f *]"}] { 
     } "Found following files to delete in dir $dir" 
     foreach f [set lf [regsub -all {\\} $lf {/}]] { 
      catch {file delete -force $f} 
     }    
    } 
    if ![catch { set ld [glob -directory $dir -type d *]}] { 
     foreach d $ld { 
      DirRecursion $d -files lf    
     } 
    } else { 
     puts "No directories to delete in dir $dir" debug 
    } 
    catch {file delete -force $dir} 
} 
+1

Я не знаю, что удаление целых каталогов параллельно будет быстрым. Скорость ограничена дисководом. –

+0

Вместо того, чтобы рассматривать 'lf' как строку, было бы лучше создать список. Используйте 'lappend'. Прямо сейчас, он, вероятно, сломает имена файлов со встроенными пространствами. Также нет необходимости в 'regsub'. 'file delete может обрабатывать собственные имена. Также представляется, что вы передаете список файлов из каталога выше в следующем вызове DirRecursion. –

ответ

3

Ну, вы могли сделать это (возможно, путем отправки запросов на file delete -force в thread pool), это очень маловероятно, чтобы помочь на всех, так как узкое место будет в реальной чтения и записи диска, даже на системах с SSD. С HDD, это определенно то, что вы будете ждать.

Вы знаете, что file delete -force уже обрабатывает рекурсивный случай удаления? Вероятно, это быстрее, чем то, что вы написали. Так как я подозреваю, что вы на самом деле не хотите, чтобы удалить самое %TEMP% пути (как это немного особенным для других программ в вашей сессии тоже), вы можете вместо этого сделать что-то вроде этого:

file delete -force {*}[glob -directory $::env(TEMP) *] 

Или удалить содержимое соответствующий подкаталог. Одна строка вместо сложной процедуры ...

Редактировать

Это будет пытаться удалить каждую запись отдельно и будет продолжаться, даже если каталог не может быть удален из-за ошибки разрешения.

foreach {entry} [glob -directory $::env(TEMP) *] { 
    catch { file delete -force $entry } 
} 
+0

Просто хотите пропустить ошибки в файлах, удаляемых при удалении, чтобы очистить беспорядок - вышеприведенная команда останавливается при первой ошибке – BabyGroot