2014-02-12 26 views
3

使用R.exeRterm.exe,這給出了一個很好的進度計。RCurl:Rgui顯示進度計

page=getURL(url="ftp.wcc.nrcs.usda.gov", noprogress=FALSE) 

在RGUI我不限於:

page=getURL(url="ftp.wcc.nrcs.usda.gov", 
      noprogress=FALSE, progressfunction=function(down,up) print(down)) 

這給出了一個非常有限的下載信息。

有沒有辦法改善這一點?

回答

3

我開始懷疑,使用標準R命令可以重新打印當前行,這是RCurl在非GUI模式下執行的操作。

我很高興地告訴我,我錯了。至少對於單行,\r可以做到這一點。事實上:

conc=function(){ 
    cat(" abcd") 
    cat(" ABCD", '\n') 

} 
conc() 

# abcd ABCD 

但是:

over=function(){ 
    cat(" abcd") 
    cat("\r ABCD", "\n") 
} 
over() 

# ABCD 

給定,我寫了這個progressDown功能,它可以監測下載的狀態在同一同一行始終改寫:

library(RCurl) # Don't forget 

### Callback function for curlPerform 
progressDown=function(down, up, pcur, width){ 
    total=as.numeric(down[1]) # Total size as passed from curlPerform 
    cur=as.numeric(down[2]) # Current size as passed from curlPerform 
    x=cur/total 
    px= round(100 * x) 
    ## if(!is.nan(x) && px>60) return(pcur) # Just to debug at 60% 
    if(!is.nan(x) && px!=pcur){ 
     x= round(width * x) 
     sc=rev(which(total> c(1024^0, 1024^1, 1024^2, 1024^3)))[1]-1 
     lb=c('B', 'KB', 'MB', 'GB')[sc+1] 
     cat(paste(c(
      "\r |", rep.int(".", x), rep.int(" ", width - x), 
      sprintf("| %g%s of %g%s %3d%%",round(cur/1024^sc, 2), lb, round(total/1024^sc, 2), lb, px)), 
        collapse = "")) 
     flush.console() # if the outptut is buffered, it will go immediately to console 
     return(px) 
    } 
    return(pcur) 
} 

現在我們可以使用回撥curlPerform

curlProgress=function(url, fname){ 
    f = CFILE(fname, mode="wb") 
    width= getOption("width") - 25 # you can make here your line shorter/longer 
    pcur=0 
    ret=curlPerform(url=url, [email protected], noprogress=FALSE, 
     progressfunction=function(down,up) pcur<<-progressDown(down, up, pcur, width), 
     followlocation=T) 
     close(f) 
     cat('\n Download', names(ret), '- Ret', ret, '\n') # is success? 
} 

用小樣本二進制運行它:

curlProgress("http://www.nirsoft.net/utils/websitesniffer-x64.zip", "test.zip") 

在60%的中間輸出是(無#保護):

|.................................      | 133.74KB of 222.75KB 60% 

其中KB,將調整爲B, KB, MB, GB,基於總尺寸。

最終輸出與成功狀態,方法是:

|.......................................................| 222.61KB of 222.75KB 100% 
Download OK - Ret 0 

注意,輸出線寬度是相對於R寬度選項(它控制的最大列數上的線)和可定製改變curlProgress line:

width= getOption("width") - 25 

這足夠滿足我的需求並解決我自己的問題。

1

什麼:

curlProgress=function(url, fname){ 
    f = CFILE(fname, mode="wb") 
    prev=0 
    ret=curlPerform(url=url, [email protected], noprogress=FALSE, 
     progressfunction=function(a,b){ 
      x=round(100*as.numeric(a[2])/as.numeric(a[1])) 
      if(!is.nan(x) && x!=prev &&round(x/10)==x/10) prev<<-x else x='.' 
      cat(x)  
     }, followlocation=T) 
    close(f) 
    cat(' Download', names(ret), '- Ret', ret, '\n') 
} 


它打印的點或百分比下載可被10整除,並在50%上打斷線。
並配有小223 KB的文件:

curlProgress("http://www.nirsoft.net/utils/websitesniffer-x64.zip", "test.zip") 

它聽起來像這樣:

................10...............20................30...............40...............50 
..............................70...............80...............90...............100... Download OK - Ret 0 

我開始懷疑,與標準R命令就可以轉載覆蓋當前行,這是什麼RCurl在非GUI模式下執行。

2

下面是一個簡單的例子,使用txtProgressBar。基本上,只需要首先執行HEAD請求以獲取要檢索的文件的文件大小,然後設置一個txtProgressBar作爲其最大大小。然後,您使用參數curlPerform來呼叫setTxtProgressBar。它的所有工作都非常好(除非沒有「內容長度」標題,在這種情況下,此代碼僅通過不打印進度條來工作)。

url <- 'http://stackoverflow.com/questions/21731548/rcurl-display-progress-meter-in-rgui' 

h <- basicTextGatherer() 
curlPerform(url=url, customrequest='HEAD', 
      header=1L, nobody=1L, headerfunction=h$update) 

if(grepl('Transfer-Encoding: chunked', h$value())) { 
    size <- 1 
} else { 
    size <- as.numeric(strsplit(strsplit(h$value(),'\r\nContent-Type')[[1]][1], 
                'Content-Length: ')[[1]][2]) 
} 

bar <- txtProgressBar(0, size) 
h2 <- basicTextGatherer() 
get <- curlPerform(url=url, noprogress=0L, 
        writefunction=h2$update, 
        progressfunction=function(down,up) 
         setTxtProgressBar(bar, down[2])) 

h2$value() # return contents of page 

整個控制檯的輸出只是一堆======