Решение проблемы прерывания загрузки в Tcl

Я загружаю список файлов, используя http-пакет tcl, и мне было интересно, как лучше всего справляться с прерываниями. Сейчас схема моей процедуры загрузки выглядит так:

proc downloadFiles {url_list folder_location} {
    foreach {i} $url_list {
        regsub {.*/(.*)$} $i {\1} $name
        set out [open $folder_location/$name w+] //not worried about errors here
        if {[catch {set token [http::geturl $i -channel $out]}]} {
            puts "Could not download $i"
        } else {
            http::cleanup $token
            puts "Downloaded $i"
        }
        close $out
    }
}

Строка, с которой у меня возникают проблемы, - это оператор catch:

catch {set token [http::geturl $i -channel $out]}

Очевидно, несмотря на то, что я отключил свой Интернет и остановил загрузку на полпути, оператор catch все еще возвращает 0 для ошибок. Есть ли способ поймать это?


person NorthGuard    schedule 21.07.2010    source источник


Ответы (1)


Обнаружить, что сеть временно исчезла, сложно (намеренно; так работает TCP / IP, а HTTP просто находится поверх этого). Что вы можете сделать, так это попытаться получить ожидаемую длину данных из заголовков HTTP и сравнить ее с длиной фактически полученных данных (вы захотите принудительно использовать двоичный режим для этого, но вы, вероятно, все равно имеете дело с двоичными данными) .

Чтобы получить ожидаемую длину данных и длину загруженных в настоящее время данных, вам понадобится немного магии с upvar (внутреннее имя псевдонима state произвольно):

upvar #0 $token state
puts "Content-Length was $state(totalsize), downloaded $state(currentsize)"

Однако обратите внимание, что многие страницы не предоставляют длину содержимого, поэтому поле totalsize равно нулю. Пакет http знает только в тех случаях, когда он дошел до конца.

При перезапуске загрузки вы захотите отправить Range заголовок. Это явно не поддерживается, поэтому вам нужно указать его с помощью параметра -headers для geturl.

http::geturl $url -headers [list Range bytes=$whereYouGotTo-]

Да, формат действительно такой классный.

person Donal Fellows    schedule 23.07.2010