首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RCurl:在Rgui中显示进度表

RCurl:在Rgui中显示进度表
EN

Stack Overflow用户
提问于 2014-02-12 15:03:01
回答 3查看 443关注 0票数 3

使用R.exeRterm.exe,这提供了一个很好的进度表。

代码语言:javascript
复制
page=getURL(url="ftp.wcc.nrcs.usda.gov", noprogress=FALSE) 

在Rgui,我仅限于:

代码语言:javascript
复制
page=getURL(url="ftp.wcc.nrcs.usda.gov", 
            noprogress=FALSE, progressfunction=function(down,up) print(down))

提供了一组非常有限的下载信息。

有什么办法可以改善这种情况吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-22 21:52:55

我开始怀疑使用标准的R命令是否有可能重写当前行,这就是RCurl在非GUI模式下所做的事情。

我很高兴地告诉你我错了。至少对于一行,\r可以做到这一点。事实上:

代码语言:javascript
复制
conc=function(){
    cat(" abcd")
    cat(" ABCD", '\n')

}
conc()

# abcd ABCD 

但是:

代码语言:javascript
复制
over=function(){
    cat(" abcd")
    cat("\r ABCD", "\n")
}
over()

# ABCD

考虑到这一点,我编写了这个progressDown函数,它可以监视下载状态重写总是在同一行上:

代码语言:javascript
复制
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中使用回调。

代码语言:javascript
复制
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, writedata=f@ref,  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? 
}

使用一个小的二进制示例运行它:

代码语言:javascript
复制
curlProgress("http://www.nirsoft.net/utils/websitesniffer-x64.zip", "test.zip")

60%的中间输出为(无#保护):

代码语言:javascript
复制
  |.................................                      | 133.74KB of 222.75KB  60%

其中KB,将根据总大小调整为B, KB, MB, GB

最后输出与成功状态,是:

代码语言:javascript
复制
  |.......................................................| 222.61KB of 222.75KB 100%
 Download OK - Ret 0 

注意,输出行宽度相对于R宽度选项(该选项控制一行上的最大列数),可以自定义更改curlProgress行:

代码语言:javascript
复制
width= getOption("width") - 25

这足以满足我的需要并解决我自己的问题。

票数 3
EN

Stack Overflow用户

发布于 2014-02-14 08:22:01

下面是一个使用txtProgressBar的简单示例。基本上,首先执行一个HEAD请求来获取要检索的文件的文件大小,然后设置一个txtProgressBar,并将其作为其最大大小。然后使用progressfunction参数来调用curlPerform来调用setTxtProgressBar。所有这些都很好地工作(除非没有“内容长度”标头,在这种情况下,这段代码只是通过不打印进度条来工作)。

代码语言:javascript
复制
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

输出只是控制台上的一堆======

票数 2
EN

Stack Overflow用户

发布于 2014-02-13 14:27:08

那麽:

代码语言:javascript
复制
curlProgress=function(url, fname){
    f = CFILE(fname, mode="wb")
    prev=0
    ret=curlPerform(url=url, writedata=f@ref,  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的小文件:

代码语言:javascript
复制
curlProgress("http://www.nirsoft.net/utils/websitesniffer-x64.zip", "test.zip")

听起来是这样的:

代码语言:javascript
复制
................10...............20................30...............40...............50 
..............................70...............80...............90...............100... Download OK - Ret 0 

我开始怀疑使用标准的R命令是否有可能重写当前行,这就是RCurl在非GUI模式下所做的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21731548

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档