r - 在 R 中将二进制文件分成更小的部分
问题描述
我有几个大文件,我想将它们转换成二进制文件。一旦它是二进制的,我想让每块小于 5GB。因此,无论有多少,都作为 R 中的对象存在。
我不确定从哪里开始,但通常我是通过伪代码。
file <- ***FILE PATH****
binFile <- writeBin(file,con)
# loop through length of 'binFile' until file.size() = 5000000 then write to a list, continue with the rest and repeat til the whole file is complete.
#Then each item in the list can be called.
如果更容易将它们作为更小的二进制文件写入我的本地也可以工作。
解决方案
您可以将一个大文件拆分为多个块,而无需将整个文件加载到内存中。这是一个可以做到这一点的函数。
你向它提供你的大文件的路径,你想要保存块的目录的路径,以及最大的块大小。
文件将全部以大文件的名称加上块号和文件类型保存.bin
。
原始文件保持不变。
如果您想将块作为二进制文件读入 R,您可以使用readBin
chop_file <- function(bigfile, save_path, chunk_size)
{
con <- file(bigfile, "rb")
pos <- 0
file_size <- file.size(bigfile)
chunk_no <- 1
filenames <- sapply(strsplit(bigfile, "/"), function(x) x[length(x)])
filenames <- gsub("[.]", "", filenames)
while(pos < file_size)
{
seek(con, pos)
data <- readBin(con, "raw", chunk_size)
pos <- seek(con, 0)
writeBin(data, paste0(save_path, filenames, chunk_no, ".bin"))
chunk_no <- chunk_no + 1
}
close(con)
message(paste(" File", bigfile, "split into", chunk_no - 1, "chunks"))
}
例如,如果我在以下目录中有一个大型二进制文件:
dir("C:/Users/Me/pdfs/")
# [1] bigfile.pdf
我希望在空目录中将它分成 1MB 块C:/Users/Me/chunks/
,我这样做:
chop_file("C:/Users/Me/pdfs/bigfile.pdf", "C:/Users/Me/chunks/", 1e6)
#> File C:/Users/Me/pdfs/bigfile.pdf split into 10 chunks
现在
dir("C:/Users/Me/chunks/")
#> [1] "bigfilepdf1.bin" "bigfilepdf2.bin" "bigfilepdf3.bin" "bigfilepdf4.bin"
#> [5] "bigfilepdf5.bin" "bigfilepdf6.bin" "bigfilepdf7.bin" "bigfilepdf8.bin"
#> [9] "bigfilepdf9.bin" "bigfilepdf10.bin"
如果您想在内存中将所有这些重新缝合在一起,您可以这样做:
data <- list()
files <- dir("C:/Users/Me/chunks/")
for(i in seq_along(files)) data[[i]] <- readBin(files[i], "raw", 10e6)
data <- do.call("c", data)
然后data
将包含原始文件的所有字节作为原始向量。
identical(data, readBin("C:/Users/Me/pdfs/bigfile.pdf", "raw", 1e7))
#> [1] TRUE
如果您希望在内存中处理块而不是将它们写入磁盘,则可以稍微简化一下:
chop_file_to_list <- function(bigfile, chunk_size)
{
con <- file(bigfile, "rb")
pos <- 0
file_size <- file.size(bigfile)
chunk_no <- 1
data <- list()
while(pos < file_size)
{
seek(con, pos)
data[[chunk_no]] <- readBin(con, "raw", chunk_size)
pos <- seek(con, 0)
chunk_no <- chunk_no + 1
}
close(con)
return(data)
}
推荐阅读
- python - “git tag -l v1.1.{[0-9],[0-9][0-9]}” 在 shell 中有效,但在 subprocess.Popen() 中无效
- raspberry-pi - 将树莓派连接到 Google Home
- python - Tensorflow,如何从张量中删除填充(特定值)
- javascript - 在移动浏览器中将覆盖滑动到整个页面 - 使用 Javascript 媒体查询
- list - 如何将单元格添加到列表中
- javascript - 如何创建搜索字段的克隆?
- ruby - Ruby 智能变量
- netsuite - 在 HTML 模板中引用自定义记录字段
- c++ - 使用成员函数启动线程(具有继承)
- c - char 双指针混淆行为