R:readBin和writeBin(用于存储/检索MySQL BLOB或LONGBLOB)

时间:2012-07-23 05:22:16

标签: r binary blob

我正在使用readBin函数将文件保存为MySQL BLOB,如本文所述(http://www.r-bloggers.com/save-r-plot-as-a-blob/

plot_binary <- paste(readBin("temp.png", what="raw", n=1e6), collapse="")

我的问题是: 一旦这在数据库中,我该如何将其转储回文件?

> f = file ( "backIntoFile.png", "wb")
> writeBin(object = plot_binary, con = f ) 
> close(f)

这不起作用;该文件似乎不是有效的png;

干杯!

4 个答案:

答案 0 :(得分:2)

如果您不使用&#34;粘贴&#34;因为它将原始数据向量更改为不能作为二进制文件写回的字符串。尝试

plot_binary <- readBin("temp.png", what="raw", n=1e6)

> f = file ( "backIntoFile.png", "wb")
> writeBin(object = plot_binary, con = f ) 
> close(f)

我已回答你的问题吗?

答案 1 :(得分:2)

这是我到目前为止找到的最佳解决方案。 DbDownloadImages函数执行的时间非常短(实际上几乎没有时间)。

# Helper function I use
Paste <- function(string, vals)
{
    string <- gsub(x = string, pattern = '\\?', replacement = "%s")
    result <- do.call(sprintf, as.list(c(string,vals)))
    return(result)
}
# conn is a RMySQL connection object
DbInsertImage <- function( conn, link.to.file ) 
{

        binary = readBin ( link.to.file , what = "raw", n = 1e6 ) 
        binary.str = paste ( binary, collapse = "" ) 
        statement = Paste ( "CALL InsertImage('?')" , c(binary.str))
        dbSendQuery(conn, statement )
        return(GetIdentity(conn)) # one of my helper functions ; 
            # it returns the "LAST INSERT ID" 
}

#conn is a RMySQL connection object 
DbDownloadImage <- function( conn, id, destination) 
{

    query = "SELECT Data FROM Image WHERE Id = ? LIMIT 1" 
    query = Paste( query, c( id ) )
    result = dbGetQuery(conn, query )$Data[1]

    sst <- strsplit(result, "")[[1]]
    result <- paste0(sst[c(TRUE, FALSE)], sst[c(FALSE, TRUE)])
    result <- as.raw ( as.hexmode ( result ) ) 

    f = file ( destination, "wb")

    writeBin(object = result, con = f ) 
    close(f)
}

另见: How to split a string into substrings of a given length?

答案 2 :(得分:0)

这是我的解决方案:

binary.string <- paste(readBin("temp.png", what="raw", n=1e6), collapse="-")
  • 将此objet作为BLOB保存到数据库中

如何从数据库下载后将其重新保存为png?

> split = strsplit ( binaryString, split = "-" )
> split = unlist ( split )
> back.to.binary = as.raw ( as.hexmode ( split ) ) 
> f = file ( "backIntoFile.png", "wb")
> writeBin(object = back.to.binary, con = f ) 
> close(f)

答案 3 :(得分:0)

好的,我在这里添加另一种解决方案。首先,要获得您可以使用的文件大小

sz <- as.integer(system("stat --format %s temp.png", intern=T))

除此之外,MadSeb的回答让我明白原始问题的真正含义。在两个字节之间添加“ - ”是一个很好的解决方案,但是,如果你必须保存1/3磁盘空间,这是一种愚蠢的方式:(需要很长时间)

plot_binary <- paste(readBin("temp.png", what="raw", n=1e6), collapse="")
theBinary <- unlist(lapply((1:(nchar(plot_binary)/2))*2, function(i)return(as.raw(as.hexmode(substr(plot_binary,i-1,i))))))