R:linux上的readBin和writeBin

R:linux上的readBin和writeBin,r,file-io,R,File Io,我想以二进制格式写入(并在以后检索)数据。我试图得到一个最小的示例,使其至少达到嗅觉测试的水平(读取输入应该看起来像写入输出),但我并没有得到正确且一致的结果。我的机器是一个带有小endian的linux,但因为这里的endian是常量,所以我在调用中使用了它。我也不确定在write中指定size参数是更好,还是省去它。无论如何,加载的输入看起来都不像out: out<-seq(1,50,2) ##write write<-file('~/output.txt','wb') wri

我想以二进制格式写入(并在以后检索)数据。我试图得到一个最小的示例,使其至少达到嗅觉测试的水平(读取输入应该看起来像写入输出),但我并没有得到正确且一致的结果。我的机器是一个带有小endian的linux,但因为这里的endian是常量,所以我在调用中使用了它。我也不确定在write中指定
size
参数是更好,还是省去它。无论如何,加载的输入看起来都不像
out

out<-seq(1,50,2)

##write
write<-file('~/output.txt','wb')
writeBin(out,con=write,size=4)
close(write)

##read
read<-file('~/output.txt','rb')
readBin(con=read,what=numeric(),n=length(out))
# [1] 3.200001e+01 3.276801e+04 1.048576e+06 1.677722e+07 1.006633e+08 4.026532e+08     1.610613e+09 6.442452e+09 1.503239e+10 3.006478e+10 6.012955e+10 1.202591e+11
close(read)

out以下是一个工作示例:

R> dat <- seq(1,50,2)
R> dat
 [1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49
R> 
R>dat-dat
[1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49
R>
我们只需将对象写入二进制连接——忽略第三个参数:

R> con <- file("/tmp/foo.bin", "wb")
R> writeBin(dat, con)
R> close(con)
R> 
R>conwritebin(dat,con)
R> 关闭(con)
R>
然后可以读回:

R> con <- file("/tmp/foo.bin", "rb")
R> dat2 <- readBin(con, what="numeric", n=length(dat))
R> dat2
 [1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49
R>
R> all.equal(dat, dat2)
[1] TRUE
R>con dat2 dat2
[1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49
R>
R> 全部相等(dat,dat2)
[1] 真的
但是,您需要存储长度。我使用了一种内部文件格式,它首先写入关于行、列、“格式编号”和。。。然后读取/写入总共行*列的数字。我们还将其包装到gzip-ed文件连接中


您甚至可以将其推广到在数据帧中写入列——但如果R是您唯一的读写器,那么通过
save()
已经存在的序列化更好。

如果您只想保存二进制数据以便以后加载到R会话中,您可以/应该改为使用
save()
load()
。(
writeBin()
readBin()
当您想要将数据传输到R之外的软件时,它们确实是自己的。)您覆盖
writeBin
中的
size
值,但不覆盖
readBin
;因此不匹配。设置两者或两者都不设置。我需要稍后使用
numpy
读取数据。长度问题很棘手。我经常有
numpy
生成的文件,我并不总是事先知道它们的长度。这正是我们的用例。我首先写了(在现有C库的情况下,让R读/写NumPy文件),然后用这里描述的更轻/更快的解决方案替换了它。当我们最初写入二进制文件时,我们知道DIM,因此可以写入头文件。