检查文件是否为二进制
Check whether file is binary
我想要一个函数 is.binary
给出以下结果
tmp_vec=1:3
save(tmp_vec,file="temp_vec.RData")
write.csv(tmp_vec,"temp_vec.csv")
is.binary("temp_vec.RData")
#TRUE
is.binary("temp_vec.csv")
#FALSE
R
有这样的功能吗?
我能想出的最佳解决方案是
is.binary=function(filename) {
is_binary=TRUE
#suppress warnings and try to read file with binary reader
#if it throws an error, set is_binary to FALSE
withCallingHandlers(expr=tryCatch(load(filename),
error=function(err) is_binary<<-FALSE),
warning=function(w) invokeRestart("muffleWarning"))
#since R loads the objects of the binary file into the memory, delete them
#maybe this is unnecessary ...
#... I do not know how R handles memory of objects that go out of scope
rm(list=ls()[ls()!="is_binary"])
is_binary
}
显然,这个函数在处理大文件时效率不是很高。任何指向更好解决方案的指示?谢谢!
编辑:我在 Windows 机器上。
计算机上的所有文件都是二进制文件。例外是那些碰巧看起来像文本文件的文件。甚至那些可能具有实际正确读取文件所需的不同编码。
如果您只是想区分 save()
和 write.csv()
的结果,最简单的检查方法是文件是否已压缩。默认情况下 save()
将压缩文件。您可以在文件中查找用于压缩的幻数。这是一种方法
is_compressed <- function(filename, magic.number=as.raw(c("0x1f","0x8b"))) {
fh<-file(filename, "rb")
on.exit(close(fh))
magic <- readBin(fh, "raw", length(magic.number))
if(length(magic) != length(magic.number)) return(FALSE)
if(all(magic == magic.number)) return(TRUE)
return (FALSE)
}
这只需要读取文件的两个字节而不是整个文件。一旦您知道它已被压缩,您就可以尝试寻找 rData 文件的幻数。这里有一个更完整的功能
is_rdata <- function(filename) {
#check for magic number
#https://github.com/wch/r-source/blob/b99d403f4b7337553acb2d2108c7a00e6c19f908/src/main/saveload.c#L1786
fh <- if(!is_compressed(filename))
file(filename, "rb")
else {
gzfile(filename, "rb")
}
on.exit(close(fh))
magic <- rawToChar(readBin(fh, "raw", 5))
if(nchar(magic)<5) return(FALSE)
if(magic %in% c("RDA1\n","RDB1\n","RDX1\n","RDA2\n","RDB2\n","RDX2\n")) return(TRUE)
return (FALSE)
}
我们可以用
进行测试
dd <- data.frame(a=1:4, b=letters[1:4])
save(dd, file="test1.file")
write.csv(dd, file="test2.file")
is_rdata("test1.file")
is_rdata("test2.file")
当然,如果您注意文件扩展名,这可能是识别文件的最简单方法。
我想要一个函数 is.binary
给出以下结果
tmp_vec=1:3
save(tmp_vec,file="temp_vec.RData")
write.csv(tmp_vec,"temp_vec.csv")
is.binary("temp_vec.RData")
#TRUE
is.binary("temp_vec.csv")
#FALSE
R
有这样的功能吗?
我能想出的最佳解决方案是
is.binary=function(filename) {
is_binary=TRUE
#suppress warnings and try to read file with binary reader
#if it throws an error, set is_binary to FALSE
withCallingHandlers(expr=tryCatch(load(filename),
error=function(err) is_binary<<-FALSE),
warning=function(w) invokeRestart("muffleWarning"))
#since R loads the objects of the binary file into the memory, delete them
#maybe this is unnecessary ...
#... I do not know how R handles memory of objects that go out of scope
rm(list=ls()[ls()!="is_binary"])
is_binary
}
显然,这个函数在处理大文件时效率不是很高。任何指向更好解决方案的指示?谢谢!
编辑:我在 Windows 机器上。
计算机上的所有文件都是二进制文件。例外是那些碰巧看起来像文本文件的文件。甚至那些可能具有实际正确读取文件所需的不同编码。
如果您只是想区分 save()
和 write.csv()
的结果,最简单的检查方法是文件是否已压缩。默认情况下 save()
将压缩文件。您可以在文件中查找用于压缩的幻数。这是一种方法
is_compressed <- function(filename, magic.number=as.raw(c("0x1f","0x8b"))) {
fh<-file(filename, "rb")
on.exit(close(fh))
magic <- readBin(fh, "raw", length(magic.number))
if(length(magic) != length(magic.number)) return(FALSE)
if(all(magic == magic.number)) return(TRUE)
return (FALSE)
}
这只需要读取文件的两个字节而不是整个文件。一旦您知道它已被压缩,您就可以尝试寻找 rData 文件的幻数。这里有一个更完整的功能
is_rdata <- function(filename) {
#check for magic number
#https://github.com/wch/r-source/blob/b99d403f4b7337553acb2d2108c7a00e6c19f908/src/main/saveload.c#L1786
fh <- if(!is_compressed(filename))
file(filename, "rb")
else {
gzfile(filename, "rb")
}
on.exit(close(fh))
magic <- rawToChar(readBin(fh, "raw", 5))
if(nchar(magic)<5) return(FALSE)
if(magic %in% c("RDA1\n","RDB1\n","RDX1\n","RDA2\n","RDB2\n","RDX2\n")) return(TRUE)
return (FALSE)
}
我们可以用
进行测试dd <- data.frame(a=1:4, b=letters[1:4])
save(dd, file="test1.file")
write.csv(dd, file="test2.file")
is_rdata("test1.file")
is_rdata("test2.file")
当然,如果您注意文件扩展名,这可能是识别文件的最简单方法。