Необработанные (двоичные) данные слишком велики для записи на диск. Как записать фрагмент на диск (добавление)? - PullRequest
0 голосов
/ 11 мая 2018

У меня есть большой необработанный вектор в R (т.е. массив двоичных данных), который я хочу записать на диск, но я получаю сообщение об ошибке, сообщающее мне, что вектор слишком велик.Вот воспроизводимый пример и ошибка, которую я получаю:

> writeBin(raw(1024 * 1024 * 1024 * 2), "test.bin")

Error in writeBin(raw(1024 * 1024 * 1024 * 2), "test.bin") : 
  long vectors not supported yet: connections.c:4147

Я заметил, что это связано с ограничением файла в 2 ГБ.Если я попытаюсь записать на один байт меньше (1024 *1024* 1024 * 2 - 1), все будет работать нормально.

Я думал о том, чтобы сделать какой-то обходной путь, когда я записываю порции большого файла на диск в пакетном режиме, только добавляя двоичные данные на диск, например:

large_file = raw(1024 * 1024 * 1024 * 2) 
chunk_size = 1024*1024*512
n_chunks = ceiling(length(large_file)/chunk_size)

for (i in 1:n_chunks)
{
  start_byte = ((i - 1) * chunk_size) + 1
  end_byte = start_byte + chunk_size - 1
  if (i == n_chunks)
    end_byte = length(large_file)
  this_chunk = large_file[start_byte:end_byte]
  appendBin(this_chunk, "test.bin") # <-- non-existing magical formula!
}

Но я не могу найти какую-либо функцию, такую ​​как "appendBin", которую я написал выше, или любую другую документацию в R, которая говорит мне, как добавлять данные прямо на диск.

Так что мой вопрос сводится к следующему:Кто-нибудь знает, как добавить необработанные (двоичные) данные к файлу , уже находящемуся на диске, без необходимости сначала считывать полный файл с диска в память?

Дополнительные сведения: В настоящее время я использую 64-разрядную версию R 3.4.2 на ПК с Windows 10 с 192 ГБ ОЗУ.Я попробовал на другом ПК (R версия 3.5 64-битная, Windows 8 с 8 ГБ оперативной памяти), и у меня возникла та же проблема.

Любая идея или обходной путь будет принята с благодарностью !!!

Спасибо!

1 Ответ

0 голосов
/ 11 мая 2018

Благодаря @MichaelChirico и @ user2554330 я смог найти обходной путь.По сути, мне просто нужно открыть файл в режиме «a + b» в качестве нового подключения и передать это подключение файла в функцию writeBin.

Вот копия рабочего кода.

large_file = raw(1024 * 1024 * 1024 * 3) 
chunk_size = 1024*1024*512
n_chunks = ceiling(length(large_file)/chunk_size)

if (file.exists("test.bin"))
  file.remove("test.bin")

for (i in 1:n_chunks)
{
  start_byte = ((i - 1) * chunk_size) + 1
  end_byte = start_byte + chunk_size - 1
  if (i == n_chunks)
    end_byte = length(large_file)
  this_chunk = large_file[start_byte:end_byte]
  output_file = file(description="test.bin",open="a+b")
  writeBin(this_chunk, output_file)
  close(output_file)
}

Я знаю, это уродливо, что я открываю и закрываю файл несколько раз, но это удерживает ошибку от появления еще больших файлов.

Еще раз спасибо за идеи,ребята!=)

...