簡體   English   中英

從文件中讀取向量

[英]Read vector from file

我有一個長度為 6.5 億的大向量。 我希望將此向量存儲在磁盤(5 GB)上,然后將整個向量加載到內存中,以便各種功能可以快速訪問其元素。

這是我在 Rcpp 中以較小規模執行此操作的嘗試。 以下代碼只是導致我的 R 會話崩潰,沒有錯誤消息。 我究竟做錯了什么?

代碼:

output_file = file(description="test.bin",open="a+b")
writeBin(runif(10), output_file,size=8)
close(output_file)

rcpp 代碼:

#include <Rcpp.h>
#include <fstream>
using namespace Rcpp;

std::vector<double> read_vector_from_file(std::string filename)
{
  std::vector<char> buffer{};
  std::ifstream ifs(filename, std::ios::in | std::ifstream::binary);
  std::istreambuf_iterator<char> iter(ifs);
  std::istreambuf_iterator<char> end{};
  std::copy(iter, end, std::back_inserter(buffer));
  std::vector<double> newVector(buffer.size() / sizeof(double));
  memcpy(&newVector[0], &buffer[0], buffer.size());
  return newVector;
}

std::vector<double> LT = read_vector_from_file("test.bin");

// [[Rcpp::export]]
double Rcpp_test() {
  return LT[3];
}

多年來,我已經為快速和骯臟的數據故事實施了幾次類似上述的方法。 這些天來,我不再推薦它,因為我們有fstqs之類的出色軟件包,它們在這方面做得更好,具有並行化、壓縮和其他功能。

但正如你所問,答案隨之而來。 我發現文件的 C API 更簡單,更接近你在 R 中所做的。所以在這里我們只是打開並讀取 10 個大小為 8 的項目(對於double ),因為這是我們知道你寫的。 我曾經對此進行了概括,並為enum類型和數字編寫了兩個int值。

代碼

#include <Rcpp.h>
#include <fstream>
using namespace Rcpp;

// [[Rcpp::export]]
Rcpp::NumericVector Rcpp_test(std::string filename, size_t size) {
    Rcpp::NumericVector v(size);
    FILE *in = fopen(filename.c_str(), "rb");
    if (in == nullptr) Rcpp::stop("Cannot open file", filename);
    auto nr = fread(&v[0], sizeof(double), size, in);
    if (nr != size) Rcpp::stop("Bad payload");
    Rcpp::Rcout << nr << std::endl;
    fclose(in);
    return v;
}

/*** R
set.seed(123)
rv <- runif(10)
filename <- "test.bin"
if (!file.exists(filename)) {
  output_file <- file(description="test.bin",open="a+b")
  writeBin(rv, output_file, size=8)
  close(output_file)
}
nv <- Rcpp_test(filename, 10)
data.frame(rv, nv)
all.equal(rv,nv)
*/

輸出

通過修復種子並比較寫入和讀取的數據,該代碼是一個輕微的概括。

> Rcpp::sourceCpp("answer.cpp")

> set.seed(123)

> rv <- runif(10)

> filename <- "test.bin"

> if (!file.exists(filename)) {
+   output_file <- file(description="test.bin",open="a+b")
+   writeBin(rv, output_file, size=8)
+   close(output_file .... [TRUNCATED] 

> nv <- Rcpp_test(filename, 10)
10

> data.frame(rv, nv)
          rv        nv
1  0.2875775 0.2875775
2  0.7883051 0.7883051
3  0.4089769 0.4089769
4  0.8830174 0.8830174
5  0.9404673 0.9404673
6  0.0455565 0.0455565
7  0.5281055 0.5281055
8  0.8924190 0.8924190
9  0.5514350 0.5514350
10 0.4566147 0.4566147

> all.equal(rv,nv)
[1] TRUE
> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM