我正在使用tcl的http包下载文件列表,并想知道处理中断的最佳方法是什么。现在我的下载程序大纲如下所示:
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表示错误。有没有办法抓住这个?
答案 0 :(得分: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-]
是的,格式确实很时髦。