Как извлечь данные из файла на FTP-сервере, не загружая все это в R? - ошибка кодирования?

Я пытаюсь получить большой набор данных (3+ ГБ) со следующего сервера:

ftp://podaac-ftp.jpl.nasa .gov/allData/ghrsst/data/L4/GLOB/JPL/MUR

Я знаю, что RCurl — хороший пакет для получения данных с FTP. Файл представляет собой сжатый файл netcdf. Мне нужно распаковать его, чтобы прочитать в R, используя ncdf4. Он сжат как bz2.

Важно отметить, что файл больше, чем я хочу на своем жестком диске, поэтому локальное сохранение копии — не идеальный вариант. Как я могу получить доступ к данным в файле без предварительного сохранения копии на моем диске?

Вот моя попытка:

library(RCurl); library(ncdf4)
d = getURL('ftp://podaac-ftp.jpl.nasa.gov/allData/ghrsst/data/L4/GLOB/JPL/MUR/2015/144/20150524-JPL-L4UHfnd-GLOB-v01-fv04-MUR.nc.bz2')
d = bzfile(d, open = 'r')
d = nc_open(d)

Но я застрял в этой загадочной ошибке после первой строки:

Error in curlPerform(curl = curl, .opts = opts, .encoding = .encoding) : 
  embedded nul in string: 'BZh91AY&SY¦ÁÀÉ\0033[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáåÏ\035\017)³îÎ\u009dÍØcn]sw7½ÎkÜÞõï=uÎׯv]ìçn\u009dÎn½îê·±Þìê÷wS­M\u008có·+ÎçW¹Ý=Ù×¹\u009cγ­ÜëÞs½ÛN¹²w;\u009buÍÝ]{·k^çuªnìº-³6«[+Üå;\033m»Û½ow:w¹ïo{uyîî\u00937¬\\Ƶl¶½\u009dÖVìç¯{ÎõïoSm]Ý×\u009eî\u008dæî®î®î\vÛÕïgW\036î®wqîÝ\\ïw«6½Þï\036Ýrë§=¬Fg·\\íåÔÙº÷gu·3\u009bKmÛ\027­Þ»\u0092îî\016îêwwm»\u009b­·s;MÞÁ½½­ÎóÍso^»q¯o;k\033iµ\u009bÛuyÝÞní5w:ï]ÓuÎo[«\033:åÞvEÜíÎç½ÝË­\u009eìQNöÔ\u008e\u0094vmÝȯg»e lÍ^\u008a©'

Кажется, это проблема с кодировкой, основанная на других подобных проблемах, но я пробовал и .encoding = 'UTF-8', и .encoding = 'ISO-8859-1', как показано в документации getURL(), но ни одна из них не работает. Я видел другие ответы на подобные проблемы, но все они, похоже, связаны с редактированием исходного файла. Однако у меня нет прав на запись в этот файл. Любая помощь?


person CephBirk    schedule 21.01.2016    source источник
comment
Как это может быть? Вы бы предпочли подождать, чтобы несколько раз загрузить 3 ГБ из сети, чем хранить их локально на своем диске - это правильно? Как вы собираетесь получить к нему доступ, если не хотите его хранить?   -  person Mark Setchell    schedule 22.01.2016
comment
Извините, уточнение: есть несколько файлов по 3 ГБ каждый. Не нужно загружать один и тот же файл несколько раз. Нет ли способа загрузить только часть данных на мой жесткий диск? Мне нужно только около 100 МБ из 3 ГБ данных из каждого файла. Нет ли способа найти файл на сервере и загрузить только то подмножество данных, которое мне нужно?   -  person CephBirk    schedule 22.01.2016


Ответы (2)


Я бы использовал httr для этого

library("httr")
library("ncdf4")
url <- 'ftp://podaac-ftp.jpl.nasa.gov/allData/ghrsst/data/L4/GLOB/JPL/MUR/2015/144/20150524-JPL-L4UHfnd-GLOB-v01-fv04-MUR.nc.bz2'
res <- GET(url, write_disk(basename(url)))
# uncompress - I used OSX's default compression tool
nc_open(sub("\\.bz2", "", res$request$output$path))

единственный шаг, который я не разобрал программно, - это разжатие файла bz2, просто сделал это с помощью инструмента OSX по умолчанию

person sckott    schedule 21.01.2016
comment
Записывает ли этот метод данные на мой жесткий диск? Файл данных превышает 3 ГБ, и я буду делать это несколько раз, поэтому локальное сохранение данных не вариант. - person CephBirk; 22.01.2016
comment
Да, httr::write_disk() записывает на диск, а не сохраняет в объект в R. Вы можете просто выполнить очистку после чтения в R, просто unlink("filename") - person sckott; 22.01.2016

Я мало что знаю о R, но вы сможете сделать это с помощью curl в режиме FTP, изменив вывод на stdout, а не на локальное имя файла, а затем используя bz2, чтобы распаковать нужный файл из его стандартного ввода.

Так, например, я могу сделать это:

curl --output - --user user:password 'ftp://127.0.0.1/somefile.bz2' | bz2 ...

Может быть, вы можете начать это изнутри R? Или сделайте fifo с:

mkfifo fifo
curl ....

а затем прочитать из файла с именем fifo в R.

Или, может быть, у R есть команда system(), и вы могли бы сделать:

system('mkfifo fifo; curl ..... | bz2 .... > fifo &')

а затем прочитать из файла с именем fifo в R.

person Mark Setchell    schedule 22.01.2016