Как заменить значение в двоичном файле в R? - PullRequest
2 голосов
/ 10 февраля 2020

Я должен работать с (пользовательским) двоичным форматом файла. Данные слишком велики для моей оперативной памяти, и мне просто нужно импортировать небольшую их часть, выполнить некоторые вычисления и перезаписать / заменить эту часть новыми значениями (поэтому я не хочу импортировать все, измените спецификацию c part и напишите все обратно).

Я попробовал комбинацию seek и writeBin, но это создает небольшой файл с моим новым значением с добавлением нулей:

fn <- tempfile()

writeBin(1L:3L, fn, size = 1L)
readBin(fn, what = "integer", size = 1L, n = 3L)
#> [1] 1 2 3

fh <- file(fn, "wb")
isSeekable(fh)
#> [1] TRUE
seek(fh, 1L, origin = "start", rw = "write")
#> [1] 0
# swap the sign of the second value
writeBin(-2L, fh, size = 1L)
close(fh)

readBin(fn, what = "integer", size = 1L, n = 3L)
#> [1]  0 -2

unlink(fn)

Использование режима ab для добавления в файл также не помогает:

fn <- tempfile()

writeBin(1L:3L, fn, size = 1L)
readBin(fn, what = "integer", size = 1L, n = 3L)
#> [1] 1 2 3

fh <- file(fn, "ab")
isSeekable(fh)
#> [1] TRUE
seek(fh, 1L, origin = "start", rw = "write")
#> [1] 3
# swap the sign of the second value
writeBin(-2L, fh, size = 1L)
close(fh)

readBin(fn, what = "integer", size = 1L, n = 3L)
#> [1] 1 2 3

unlink(fn)

Мой ожидаемый результат будет 1 -2 3.

Есть ли способ сделать это в R или я должен использовать C для этого?

1 Ответ

0 голосов
/ 12 февраля 2020

После некоторых проб и ошибок я сам нашел решение: использование режима "r+b" поддерживает замену данных.

fn <- tempfile()

writeBin(1L:3L, fn, size = 1L)
readBin(fn, what = "integer", size = 1L, n = 3L)
#> [1] 1 2 3

fh <- file(fn, "r+b")
isSeekable(fh)
#> [1] TRUE
seek(fh, 1L, origin = "start", rw = "write")
#> [1] 0
# swap the sign of the second value
writeBin(-2L, fh, size = 1L)
close(fh)

readBin(fn, what = "integer", size = 1L, n = 3L)
#> [1]  1 -2  3

unlink(fn)

Я не пробовал этого раньше, потому что документация Режимы в ?file не предоставляют эту информацию:

'"wb"' Открыто для записи в двоичном режиме.

'"ab"' Открыто для добавление в двоичном режиме.

'"r +"', '"r + b"' Открыть для чтения и записи.

...